我有一个 Bash 脚本,它启动一个 Web 服务器,执行一些工作,然后启动第二个 Web 服务器。我希望脚本退出,并且如果服务器退出或用户输入Ctrl+ ,则这两个服务器都终止C。
我现在拥有的看起来像这样:
start_server_1 &
server_1_pid=$!
trap "kill $server_1_pid" EXIT
# ...do some work that requires server 1 to be running...
start_server_2 || exit $?
如果用户键入Ctrl+ ,这会正确关闭两台服务器C。但是,如果服务器 1 退出,则服务器 2 和脚本本身将继续运行。如果这些进程之一退出,如何确保服务器和脚本都将被关闭?
答案1
在后台运行这两个进程,然后wait -n
等待其中一人退出。
Bash 不会报告哪个进程退出,但您可以运行jobs -p
获取仍在运行的后台作业列表并杀死它们。
start_server_1 &
server_1_pid=$!
start_server_2 &
server_2_pid=$!
wait -n
kill $(jobs -p)
wait -n
是 bash 4.3 中的新增内容。在旧版本中,这样做要困难得多。
其他常见 shell 没有wait -n
,但它们允许您在 SIGCHLD 上设置陷阱并调用 plain wait
。在 dash、ksh93、mksh 和 zsh 中,您可以编写
trap 'kill $server_1_pid $server_2_pid; exit' CHLD
wait
这在 bash 中不起作用,因为只有在所有作业完成运行后才会调用 SIGCHLD 陷阱。