在 Bash 脚本中,我想执行以下操作:
app1 &
pidApp1=$!
app2 &
pidApp2=$1
timeout 60 wait $pidApp1 $pidApp2
kill -9 $pidApp1 $pidApp2
即,在后台启动两个应用程序,并给它们 60 秒的时间来完成它们的工作。然后,如果他们没有在该间隔内完成,则杀死他们。
不幸的是,上面的方法不起作用,因为 timeout
是一个可执行文件,而 wait
是一个 shell 命令。我尝试将其更改为:
timeout 60 bash -c wait $pidApp1 $pidApp2
但这仍然不起作用,因为 wait
只能在同一个 shell 中启动的 PID 上调用。
有什么想法吗?
最佳答案
您的示例和接受的答案都过于复杂,为什么您不仅使用 timeout
,因为那是 正是它的用例? timeout
命令甚至有一个内置选项 (-k
) 在发送终止命令的初始信号 (SIGTERM) 后发送
默认情况下)如果在发送初始信号后命令仍在运行(参见 SIGKILL
man timeout
)。
如果脚本不一定需要 wait
并在等待后恢复控制流,这只是
timeout -k 60s 60s app1 &
timeout -k 60s 60s app2 &
# [...]
但是,如果确实如此,则只需保存 timeout
PID 即可:
pids=()
timeout -k 60s 60s app1 &
pids+=($!)
timeout -k 60s 60s app2 &
pids+=($!)
wait "${pids[@]}"
# [...]
例如
$ cat t.sh
#!/bin/bash
echo "$(date +%H:%M:%S): start"
pids=()
timeout 10 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 1 terminated successfully"' &
pids+=($!)
timeout 2 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 2 terminated successfully"' &
pids+=($!)
wait "${pids[@]}"
echo "$(date +%H:%M:%S): done waiting. both jobs terminated on their own or via timeout; resuming script"
.
$ ./t.sh
08:59:42: start
08:59:47: job 1 terminated successfully
08:59:47: done waiting. both jobs terminated on their own or via timeout; resuming script
https://stackoverflow.com/questions/10028820/