在bash中,我可以通过pid
变量获取最后一个子进程的进程ID($!
)。然后我可以在它完成之前终止这个子进程:
(sleep 5) & pid=$!
kill -9 $pid
这与宣传的一样。如果我现在在sleep
之后使用更多命令扩展子进程,则在子进程被终止后继续sleep
命令,即使其他命令永远不会被执行。
作为一个例子,考虑以下内容,它使用ps
旋转子进程并监视其暗杀:
# Start subprocess and get its pid
(sleep 5; echo done) & pid=$!
# grep for subprocess
echo "grep before kill:"
ps aux | grep "$pid\|sleep 5"
# Kill the subprocess
echo
echo "Killing process $pid"
kill -9 $pid
# grep for subprocess
echo
echo "grep after kill:"
ps aux | grep "$pid\|sleep 5"
# Wait for sleep to finish
sleep 6
# grep for subprocess
echo
echo "grep after sleep is finished:"
ps aux | grep "$pid\|sleep 5"
如果我将其保存到名为filename
的文件并运行它,我会得到此打印输出:
grep before kill:
username 7464 <...> bash filename
username 7466 <...> sleep 5
username 7467 <...> grep 7464\|sleep 5
Killing process 7464
grep after kill:
username 7466 <...> sleep 5
username 7469 <...> grep 7464\|sleep 5
grep after sleep is finished:
username 7472 <...> grep 7464\|sleep 5
来自ps
命令的不重要信息被<...>
替换。看起来kill
已经杀死filename
的整体bash执行,同时让sleep
继续运行。
如何正确终止整个子流程?
答案 0 :(得分:1)
您可以查看似乎符合您要求的rkill
:
http://www.unix.com/man-page/debian/1/rkill/
rkill [-SIG] pid / name ...
当作为rkill调用时,此实用程序不显示有关进程的信息,但是 向他们发送所有信号。如果未在命令行中指定,则终止 发送(SIGTERM)信号。
答案 1 :(得分:1)
您可以在子shell中设置陷阱以在退出之前终止所有活动作业:
(trap 'kill $(jobs -p)' EXIT; sleep 5; echo done ) & pid=$!
答案 2 :(得分:1)
我不知道究竟为什么睡眠过程变得孤儿,反正杀了你可以使用pkill -P标志来还杀死所有孩子
pkill -TERM -P $pid
编辑: 这意味着为了杀死一个进程及其所有的孩子你应该使用
CPIDS=`pgrep -P $pid` # gets pids of child processes
kill -9 $pid
for cpid in $CPIDS ; do kill -9 $cpid ; done