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

时间:2012-01-26 18:18:36

标签: bash process signals

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

run_development_webserver.sh
watch_sass_files_and_compile_them.sh
watch_coffeescript_files_and_compile_them.sh

我想并行运行它们,并通过点击^ C将它们全部杀死。这是可能的,如果可以,我该怎么做?

1 个答案:

答案 0 :(得分:36)

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

trap

#!/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

这会在后台启动每个命令(&),将其流程ID($!)放入数组(PIDS[x]=$!),告诉bash {当您的脚本获得kill信号( Ctrl + C ),然后{{1}时,{1}}全部(${PIDS[*]) } s用于退出所有进程。

我会主动提及SIGINT在您创建wait时展开"kill ${PIDS[*]}";如果您将双引号(PIDS)更改为单引号(trap),则会在"执行时进行扩展,这意味着您可以向'添加更多进程设置trap之后,它也会杀死它们。

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

SIGKILL

如果它没有回复trap,请单独保存该进程的pid,例如在trap "kill -TERM ${PIDS[*]}" SIGINT 中,并使用此代码:

SIGTERM

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