How to Kill Current Command When Bash Script is Killed
我目前有一个像这样的脚本。
1 2 3 4 5 | # code mplayer"$vid" # more code |
问题在于,如果该脚本被杀死,则mplayer进程将继续运行。我想知道如何做到这一点,以便杀死脚本也将杀死mplayer。
我不能使用
1 | exec mplayer"$vid" |
我能想到的唯一可能的解决方案是在后台生成它,然后等待它手动完成。这样,我可以获取它的PID并在脚本被杀死时将其杀死,而不是很优雅。我想知道这样做的"正确"或最佳方法是什么。
我能够测试我在评论中发布的prctl想法,而且似乎可行。您将需要编译以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <wyn> #include"sys/prctl.h" #include"stdlib.h" #include"string.h" #include"unistd.h" int main(int argc, char ** argv){ prctl(PR_SET_PDEATHSIG, atoi(argv[1]),0,0,0); char * argv0 = strdup(argv[2]); char * slashptr = strrchr(argv0, '/'); if(slashptr){ argv0 = slashptr + 1; } return execvp(argv0, &(argv[2])); } </wyn> |
假设您已将上面的代码编译为一个名为" prun"的可执行文件,并且该文件位于您的路径中。假设您的脚本称为" foo.sh",并且它也在您的路径中。制作一个调用的package器脚本
当package器脚本由于任何原因而终止时,即使
foo.sh也应获得SIGTERM。
注意:这是仅Linux的解决方案,显示的c源代码没有详细检查参数
感谢Mux的带领。看来,除了手动捕获信号外,没有其他方法可以在bash中执行此操作。这是最终的工作版本(注释过多)。
1 2 3 4 5 6 7 8 9 | trap : SIGTERM SIGINT # Trap these two (killing) signals. These will cause wait # to return a value greater than 128 immediately after received. mplayer"$vid" & # Start in background (PID gets put in `$!`) pid=$! wait $pid # Wait for mplayer to finish. [ $? -gt 128 ] && { kill $pid ; exit 128; } ; # If a signal was recieved # kill mplayer and exit. |
推荐人:
-陷阱:http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html
好吧,您可以简单地杀死进程组,这样整个进程树将被杀死,首先找出组ID
1 | ps x -o "%p %r %c" | grep <name> |
然后像这样使用kill:
1 | kill -TERM -<gid> |
请注意过程组ID之前的破折号。还是单线:
1 | kill -TERM -$(pgrep <name>) |
(已更新),我想我了解您正在寻找的内容:
您可以通过产生一个新的终端来运行脚本来完成此任务:
1 | gnome-terminal -x /path_to_dir_of_your_script/your_script_name |
(或使用
因此,现在每当脚本结束/退出时(我假设脚本的某些部分具有
例如,我刚刚使用以下脚本测试了上述命令:
1 2 3 4 5 6 7 8 | #!/bin/bash gedit & pid=$! echo"$pid" sleep 5 exit 0 |
如您所见,没有明确的调用来杀死新的
(先前的回答:或者,如果您只是询问如何终止进程),这是一个简短示例,说明如何使用
1 2 3 4 5 6 7 8 | #!/bin/bash gedit & pid=$! echo"$pid" sleep 5 kill -s SIGKILL $pid |
除非我误解了您的问题,否则您可以立即获取生成的进程的PID,而不必等到完成为止。
也许使用命令替换在子shell中运行
1 | $(mplayer"$vid") |
我以此方式进行了测试:
tesh.sh:
1 2 3 | #!/bin/sh $vid ="..." $(mplayer"$vid") |
1 | % test.sh |
在单独的终端中:
1 | % pkill test.sh |
在原始终端中,mplayer停止,打印到stderr
1 2 | Terminated MPlayer interrupted by signal 13 in module: av_sync |