如何在 linux 的后台停止脚本 运行?
How do I stop a scirpt running in the background in linux?
假设我有一个愚蠢的脚本:
while true;do
touch ~/test_file
sleep 3
done
然后我将脚本启动到后台并离开终端:
chmod u+x silly_script.sh
./silly_script.sh &
exit
我现在有办法识别并停止该脚本吗?我的看法是,每个命令都是在它自己的进程中启动的,我可能能够捕获并终止一个命令,如 'sleep 3' 但不是整个脚本的执行,我错了吗?我希望一个进程以脚本名称出现,但它没有。如果我用 'source silly_script.sh' 启动脚本,我找不到名为 'source' 的进程。我是否需要识别正在执行脚本的 bash 的实例?我该怎么做?
编辑:有一些创造性的解决方案,但到目前为止,它们需要立即存储脚本执行的 PID,或者 bash 会话不与 ^D
一起保留或 exit
。我明白,这种 运行 脚本的方式应该避免,但我很难相信,任何低权限用户都可以,即使是意外地,在后台启动一个烦人的脚本,例如填充带有垃圾文件的驱动器或重复启动某些软件的新实例,甚至管理员也别无选择,只能重新启动服务器,因为一个简单的脚本甚至可以在不尝试的情况下隐藏它的标识符。
jobs
命令将显示所有 运行 后台作业。
您可以使用 kill 通过 id 终止后台作业,例如:
$ sleep 9999 &
[1] 58730
$ jobs
[1]+ Running sleep 9999 &
$ kill %1
[1]+ Terminated sleep 9999
$ jobs
$
58730
是后台任务的PID,1
是它的任务id。在这种情况下 kill 58730
和 kill %1` 会产生相同的效果。
有关详细信息,请参阅 man bash
的 JOB CONTROL
部分。
当您退出时,后台作业将收到终止信号并死掉(假设这就是它处理信号的方式 - 在您的简单示例中就是这样),除非您先 disown
它。
kill 将传播到 sleep
进程,该进程可能会忽略它并继续休眠。如果是这种情况,您仍然会在 ps -e
输出中看到它,但是父 pid 为 1 表示其原始父不再存在。
您可以使用 ps -o ppid= <pid>
查找进程的父级,或 pstree -ap
可视化作业层次结构并直观地找到父级。
在这里优秀的人的帮助下,我得到了我需要的答案:
的确,脚本 运行 在它自己的进程中包含每个命令,因此例如终止 sleep 3
命令不会对脚本 运行 做任何事情,而是通过命令与 sleep 3
一样,您可以通过查找父进程找到 bash 实例 运行ning 脚本:
所以在完成以上操作后,你可以运行 ps axf
以树的形式显示所有进程。然后你会发现这个部分:
18660 ? S 0:00 /bin/bash
18696 ? S 0:00 \_ sleep 3
现在您已经找到 bash 实例,即 运行ning 脚本并可以停止它:kill 18660
(当然你的PID会和我的不一样)
假设我有一个愚蠢的脚本:
while true;do
touch ~/test_file
sleep 3
done
然后我将脚本启动到后台并离开终端:
chmod u+x silly_script.sh
./silly_script.sh &
exit
我现在有办法识别并停止该脚本吗?我的看法是,每个命令都是在它自己的进程中启动的,我可能能够捕获并终止一个命令,如 'sleep 3' 但不是整个脚本的执行,我错了吗?我希望一个进程以脚本名称出现,但它没有。如果我用 'source silly_script.sh' 启动脚本,我找不到名为 'source' 的进程。我是否需要识别正在执行脚本的 bash 的实例?我该怎么做?
编辑:有一些创造性的解决方案,但到目前为止,它们需要立即存储脚本执行的 PID,或者 bash 会话不与 ^D
一起保留或 exit
。我明白,这种 运行 脚本的方式应该避免,但我很难相信,任何低权限用户都可以,即使是意外地,在后台启动一个烦人的脚本,例如填充带有垃圾文件的驱动器或重复启动某些软件的新实例,甚至管理员也别无选择,只能重新启动服务器,因为一个简单的脚本甚至可以在不尝试的情况下隐藏它的标识符。
jobs
命令将显示所有 运行 后台作业。
您可以使用 kill 通过 id 终止后台作业,例如:
$ sleep 9999 &
[1] 58730
$ jobs
[1]+ Running sleep 9999 &
$ kill %1
[1]+ Terminated sleep 9999
$ jobs
$
58730
是后台任务的PID,1
是它的任务id。在这种情况下 kill 58730
和 kill %1` 会产生相同的效果。
有关详细信息,请参阅 man bash
的 JOB CONTROL
部分。
当您退出时,后台作业将收到终止信号并死掉(假设这就是它处理信号的方式 - 在您的简单示例中就是这样),除非您先 disown
它。
kill 将传播到 sleep
进程,该进程可能会忽略它并继续休眠。如果是这种情况,您仍然会在 ps -e
输出中看到它,但是父 pid 为 1 表示其原始父不再存在。
您可以使用 ps -o ppid= <pid>
查找进程的父级,或 pstree -ap
可视化作业层次结构并直观地找到父级。
在这里优秀的人的帮助下,我得到了我需要的答案:
的确,脚本 运行 在它自己的进程中包含每个命令,因此例如终止 sleep 3
命令不会对脚本 运行 做任何事情,而是通过命令与 sleep 3
一样,您可以通过查找父进程找到 bash 实例 运行ning 脚本:
所以在完成以上操作后,你可以运行 ps axf
以树的形式显示所有进程。然后你会发现这个部分:
18660 ? S 0:00 /bin/bash
18696 ? S 0:00 \_ sleep 3
现在您已经找到 bash 实例,即 运行ning 脚本并可以停止它:kill 18660
(当然你的PID会和我的不一样)