我有一个bash脚本,它在循环中执行一些并行处理。我不希望并行进程加速CPU,所以我使用sleep命令。这是一个简化版本。
(while true;do sleep 99999;done)&
所以我从bash提示符执行上面的行,得到类似的东西:
[1] 12345
其中[1]
是作业编号,12345
是while循环的进程ID(pid)。我做了kill 12345
并得到:
[1]+ Terminated ( while true; do sleep 99999; done )
看起来整个脚本已经终止。但是,我做了一个ps aux|grep sleep
并发现sleep命令仍然很强大,但有自己的pid!我可以杀死sleep
,一切似乎都很好。但是,如果我先杀死睡眠,则while循环会启动一个新的sleep
pid。这对我来说是一个惊喜,因为睡眠与while循环并不平行。循环本身就是一条执行路径。
所以我有两个问题:
答案 0 :(得分:5)
PID
,因为它是一个正在运行的进程,只是在等待。请尝试which sleep
查看它的位置。ps -uf
查看系统上的进程树。从那里你可以确定睡眠的shell(运行循环的那个)的PPID
(父PID)是什么。答案 1 :(得分:1)
您是否尝试过kill %1
,其中1
是您在后台启动命令后获得的数字?
我在启动(while true;do sleep 99999;done)&
后立即执行了此操作并正确终止了它。
答案 2 :(得分:1)
“ps --ppid”选择具有指定父pid的所有进程,例如:
$ (while true;do sleep 99999;done)&
[1] 12345
$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)
答案 3 :(得分:1)
您可以终止进程组。
要查找流程运行的流程组:
ps --no-headers -o "%r" -p 15864
然后使用以下方法终止进程组:
kill -- -[PGID]
您可以在一个命令中完成所有操作。我们试一试:
$ (while true;do sleep 99999;done)&
[1] 16151
$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+ Terminated ( while true; do
sleep 99999;
done )
答案 4 :(得分:1)
因为"睡眠"是一个过程,而不是内置函数或类似的
您可以执行以下操作:
(while true;do sleep 99999;done)&
whilepid=$!
kill -- -$whilepid
上述代码会终止进程组,因为PID被指定为负数(例如-123而不是123)。此外,它使用变量$!
,它存储最近执行的进程的PID。
注意: 当您在交互模式下在后台执行任何进程时(即使用命令行提示符),它会创建一个新的进程组,这就是您正在发生的事情。这样,它可以相对容易地杀死所有人,因为你只需杀死整个进程组。但是,当在脚本中完成相同操作时,它不会创建任何新组,因为所有新进程都属于脚本PID,即使它们是在后台执行的(默认情况下禁用作业控制)。要在脚本中启用作业控制,只需将以下内容放在脚本的开头:
#!/bin/bash
set -m
答案 5 :(得分:0)
要使用while
来终止sleep
循环和$!
,您还可以在子shell中使用trap
信号处理程序。
(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}