如何获得一组后台命令的正确PID并将其杀死?

时间:2013-06-06 13:15:33

标签: linux bash shell

好的,就像在这个帖子How to get PID of background process?中一样,我知道如何获得后台进程的PID。但是,我需要做的事情不止一次。

{
           sleep 300;

           echo "Still running after 5 min, killing process manualy.";
           COMMAND COMMAND COMMAND

           echo "Shutdown complete"
}&
PID_CHECK_STOP=$!
some stuff...
kill -9 $PID_CHECK_STOP

但它不起作用。似乎我得到了一个糟糕的PID或者我无法杀死它。我试着运行ps | grep sleep和它给出的pid总是在我进入PID_CHECK_STOP的那个旁边。有没有办法让它发挥作用?我可以用其他方式包装这些命令,这样我可以在需要时将它们全部杀死吗?

Thx伙计们!

3 个答案:

答案 0 :(得分:2)

kill -9会杀死该进程,然后才能执行任何其他操作,包括通知其子进程退出。使用更温和的信号(kill本身,发送一个TERM,应该足够了)。但是,您需要通过trap命令明确地让进程发信号通知其子节点(如果有)。

我假设sleep是实际命令的占位符。然而,sleep是棘手的,因为它会在它返回之前忽略任何信号(即,它是不可中断的)。要使您的示例正常工作,请将sleep本身放在后台并立即wait。当您终止“外部”后台进程时,它将中断wait调用,这也将导致sleep被杀死。

{
       trap 'kill $(jobs -p)' EXIT
       sleep 300 & wait

       echo "Still running after 5 min, killing process manualy.";
       COMMAND COMMAND COMMAND

       echo "Shutdown complete"
}&
PID_CHECK_STOP=$!
some stuff...
kill $PID_CHECK_STOP

更新:COMMAND COMMAND COMMAND包含一个通过sudo运行的命令。要终止该过程,还必须通过kill运行sudo。请记住,这样做会运行外部kill程序,而不是内置的shell(两者之间没有什么区别;内置存在允许您在进程配额已经过程时终止进程)到达)。

答案 1 :(得分:1)

您可以使用包含这些命令的其他脚本并终止该脚本。如果您是动态生成块的代码,只需写出一个脚本,执行它并在完成后终止。

答案 2 :(得分:0)

语句周围的{ ... }启动一个新的shell,之后你会得到 PID。 sleep和块中的其他命令获得单独的PID。

为了说明,在ps afux | less中查找您的流程 - 父shell流程(在sleep之上)具有您刚刚给出的PID。