我目前有一个看起来像这样的脚本。
# code
mplayer "$vid"
# more code
问题是如果这个脚本被杀死,mplayer进程就会存在。我想知道我怎么能这样做,以便杀死脚本也会杀死mplayer。
我无法使用exec
,因为我需要在mplayer之后运行命令。
exec mplayer "$vid"
我能想到的唯一可行解决方案是在后台生成它并等到手动完成。这样我可以得到它的PID并在脚本被杀死时杀死它,而不是完全优雅。我想知道这样做的“正确”或最佳方式是什么。
答案 0 :(得分:4)
我能够在评论中测试我发布的prctl想法,它似乎有效。你需要编译这个:
#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]));
}
假设您已将上述内容编译为名为“prun”的可执行文件,并且它位于您的路径中。假设您的脚本名为“foo.sh”,它也在您的路径中。制作一个调用
的包装脚本
prun 15 foo.sh
foo.sh应该得到SIGTERM,甚至是SIGKILL。
注意:这是一个仅限Linux的解决方案,所提供的c源代码没有详细检查参数
答案 1 :(得分:3)
感谢Mux领先。除了手动捕获信号外,似乎没有办法在bash中执行此操作。这是最终的工作(过度评论)版本。
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.
Refrences: - 陷阱:http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html
答案 2 :(得分:2)
(已更新)我想我理解您现在正在寻找的内容:
您可以通过生成一个新终端来运行您的脚本来完成此任务:
gnome-terminal -x /path_to_dir_of_your_script/your_script_name
(或使用xterm -e
或konsole -e
代替gnome-terminal -x
,具体取决于您所使用的系统)
所以现在每当你的脚本结束/退出时(我假设你在脚本的某些部分有exit 0
或exit 1
),新生成的终端也将退出,因为脚本已经完成 - 这将是反过来也会杀死在这个新终端下产生的任何应用程序。
例如,我刚用这个脚本测试了上面的命令:
#!/bin/bash
gedit &
pid=$!
echo "$pid"
sleep 5
exit 0
正如您所看到的,没有显式调用来终止新的gedit
进程,但是一旦脚本退出,应用程序(gedit)就会关闭。
(以前的回答:或者,如果您只是询问如何杀死一个过程)以下是一个简短的示例,说明如何使用kill
完成此任务。
#!/bin/bash
gedit &
pid=$!
echo "$pid"
sleep 5
kill -s SIGKILL $pid
除非我误解了您的问题,否则您可以立即获得生成过程的PID,而不是等到它完成。
答案 3 :(得分:2)
好吧,你可以简单地杀掉进程组,这样整个进程树就会被杀掉,先找出组ID
ps x -o "%p %r %c" | grep <name>
然后像这样使用kill:
kill -TERM -<gid>
请注意进程组ID之前的短划线。或者单行:
kill -TERM -$(pgrep <name>)
答案 4 :(得分:0)
也许使用command substitution在子shell中运行mplayer "$vid"
:
$(mplayer "$vid")
我用这种方式测试了它:
tesh.sh:
#!/bin/sh
$vid = "..."
$(mplayer "$vid")
% test.sh
在另一个终端:
% pkill test.sh
在原始终端中,mplayer停止,打印到stderr
Terminated
MPlayer interrupted by signal 13 in module: av_sync