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

标签 bash process signals

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

run_development_webserver.sh
watch_sass_files_and_compile_them.sh
watch_coffeescript_files_and_compile_them.sh

我想并行运行它们中的每一个,然后按 ^C 将它们全部杀死。这可能吗?如果可以,我该怎么做?

最佳答案

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

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 当你的脚本得到一个 >SIGINT 信号(Ctrl+C),然后等待所有进程退出。

我会主动提到当您创建陷阱时,"kill ${PIDS[*]}" 会扩展PIDS;如果把双引号(")改成单引号('),在执行trap时会展开,也就是说你可以在设置trap 后向PIDS 添加更多进程,它也会杀死它们。

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

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

如果它不响应 SIGTERM,请单独保存该进程的 pid,例如 STUBBORN_PID,然后使用:

trap "kill ${PIDS[*]}; kill -KILL $STUBBORN_PID" SIGINT

请记住,这个不会让顽固的进程清理,但如果它需要死而没有死,您可能仍然需要使用它。

关于bash - 在 Bash 中,如何运行多个无限运行的命令并使用 ^C 将它们全部取消?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9023164/

相关文章:

linux - Sed 在 shell 脚本中用 Control-A 替换制表符

Xmlstarlet,多个元素和日期排除

c - 将参数传递给 C 中的信号处理程序

c++ - 将浮点异常转换为 C++ 异常

python - 尽管有 uid,Django 后保存信号被调用两次

python - 采购 python 脚本

bash - 使用 Bash 脚本循环删除多个文件的第一行

java - 为什么这段java代码会卡住?

visual-studio - 无法使用 VS2010 附加到 Silverlight 应用程序

c - 这个代码段告诉我什么?