在Bash中,如何运行多个无限运行的命令并使用^ C取消它们?

Rud*_*ski 13 bash signals process

我想写一个运行一些不同的无限运行命令的脚本,例如

run_development_webserver.sh
watch_sass_files_and_compile_them.sh
watch_coffeescript_files_and_compile_them.sh
Run Code Online (Sandbox Code Playgroud)

我想并行运行每一个,并通过点击^ C杀死它们.这是可能的,如果是这样,我该怎么做?

Kev*_*vin 37

我会让海军上将阿克巴回答这个问题.

陷阱

#!/bin/bash -e

run_development_webserver.sh &
PIDS[0]=$!
watch_sass_files_and_compile_them.sh &
PIDS[1]=$!
watch_coffeescript_files_and_compile_them.sh & 
PIDS[2]=$!

trap "kill ${PIDS[*]}" SIGINT

wait
Run Code Online (Sandbox Code Playgroud)

这将启动每个在后台(你的命令&),把它们的进程ID( $!)到一个数组(PIDS[x]=$!),告诉bashkill他们全部(${PIDS[*])当你的脚本得到一个SIGINT信号(Ctrl+ C),然后wait献给所有进程退出.

我会主动提到当你创建时"kill ${PIDS[*]}"扩展; 如果你将双引号()更改为单引号(),它将在执行时展开,这意味着你可以在设置后添加更多进程,它也会杀死它们.PIDStrap"'trapPIDStrap

如果你有一个不想在Ctrl+ C(SIGINT)之后退出的顽固过程,你可能需要向它发送一个更强的杀戮信号 - SIGTERM或者甚至SIGKILL(作为最后的手段使用它,它无条件地杀死这个过程而不给它一个机会清理).首先,尝试将trap行更改为:

trap "kill -TERM ${PIDS[*]}" SIGINT
Run Code Online (Sandbox Code Playgroud)

如果它没有响应SIGTERM,请单独保存该进程的pid,比如说STUBBORN_PID,并使用:

trap "kill ${PIDS[*]}; kill -KILL $STUBBORN_PID" SIGINT
Run Code Online (Sandbox Code Playgroud)

请记住,这个不会让顽固的过程清理干净,但如果它需要死亡而不是,你可能还是需要使用它.

  • 快速,图像宏,_和_正确的答案?**开始上升.** (3认同)