mae*_*o21 17 shell signals process-management background-process
我想在 Linux 机器上的 bash 中同时运行两个命令。因此,在我的./execute.sh
bash 脚本中,我输入了:
command 1 & command 2
echo "done"
Run Code Online (Sandbox Code Playgroud)
但是,当我想停止 bash 脚本并点击Ctrl+ 时C,只停止第二个命令。第一个命令继续运行。如何确保停止完整的 bash 脚本?或者无论如何,我如何停止这两个命令?因为在这种情况下,无论我按Ctrl+多少次C,命令都会继续运行,我不得不关闭终端。
mic*_*has 19
如果你输入
command 1 & command 2
Run Code Online (Sandbox Code Playgroud)
这等于
command 1 &
command 2
Run Code Online (Sandbox Code Playgroud)
即这将在后台运行第一个命令,然后在前台运行第二个命令。特别是这意味着,即使仍在运行,您echo "done"
也会在command 2
完成后打印command 1
。
你可能想要
command 1 &
command 2 &
wait
echo "done"
Run Code Online (Sandbox Code Playgroud)
这将在后台运行这两个命令并等待两者完成。
如果您按 CTRL-C,这只会将 SIGINT 信号发送到前台进程,即command 2
在您的版本中或wait
在我的版本中。
我建议设置一个这样的陷阱:
#!/bin/bash
trap killgroup SIGINT
killgroup(){
echo killing...
kill 0
}
loop(){
echo $1
sleep $1
loop $1
}
loop 1 &
loop 2 &
wait
Run Code Online (Sandbox Code Playgroud)
使用陷阱,CTRL-C 产生的 SIGINT 信号被捕获并替换为killgroup
函数,该函数会杀死所有这些进程。
小智 7
从脚本将命令置于后台时,PID 不会显示在屏幕上。您可以使用$!
存储最后一个进程的 PID的内置变量,以便您可以捕获 command1 的 PID。
command1 &
echo $!
Run Code Online (Sandbox Code Playgroud)
将回显 command1 的 PID。
Bash 还提供了内置的陷阱,您可以使用它来注册一系列命令,以便在接收到特定信号时运行。您可以在退出主脚本之前使用它来捕获 SIGINT 并杀死 command1,例如
#!/bin/bash
onINT() {
echo "Killing command1 $command1PID too"
kill -INT "$command1PID"
exit
}
trap "onINT" SIGINT
command1 &
command1PID="$!"
comamnd2
echo Done
Run Code Online (Sandbox Code Playgroud)
现在,当命令 2 正在运行时,击中Ctrl C将导致命令 1和命令 2 都被发送 SIGINT。
较新版本的 GNU Parallel 可以满足您的需求:
parallel ::: "command 1" "command 2"
echo "done"
Run Code Online (Sandbox Code Playgroud)
或者如果command
保持不变:
parallel command ::: 1 2
echo done
Run Code Online (Sandbox Code Playgroud)
观看介绍视频以进行快速介绍:https : //www.youtube.com/playlist?list=PL284C9FF2488BC6D1
完成教程 (man parallel_tutorial)。你爱你的命令行。