Bash:杀死子进程

时间:2017-01-06 15:16:39

标签: linux bash shell unix kill

在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继续运行。

如何正确终止整个子流程?

3 个答案:

答案 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