Oli*_*aum 5 shell bash concurrency exit-status
我正在运行多个进程,如果其中任何一个进程失败或存在,我想使用适当的退出代码退出(这意味着失败时出错,否则成功)。
此外,如果任何子进程退出或失败,任何其他子进程也应关闭。
我当前的非功能性解决方案(纱线只是一个例子;可能是任何其他命令):
#!/bin/bash -e
# Run other process before start
sh ./bin/optimize.sh
trap 'exit' INT TERM
trap 'kill -INT 0' EXIT
# Run Schedule
sh ./bin/schedule.sh &
# Run a long running task
yarn task &
wait
Run Code Online (Sandbox Code Playgroud)
./bin/schedule.sh:
#!/bin/bash -e
while true; do
yarn schedule
sleep 30
done
Run Code Online (Sandbox Code Playgroud)
如果某些内容yarn schedule失败,则一切都正确存在。但是当我通过ctrl+c或yarn taskexitsyarn schedule终止进程时,它会继续运行。
无论子进程是什么(bash、yarn、php 或其他),如何让它工作?
我不能使用 GNU 并行。
这在 shell 中是很痛苦的,因为wait内置函数不会对任何 \xe2\x80\x9d 执行 \xe2\x80\x9cwait,而是对所有 \xe2\x80\x9c 执行 \xe2\x80\x9dwait。wait不带参数等待所有子进程退出,并返回 0。wait使用显式进程列表等待所有子进程退出,并返回最后一个参数的状态。要等待多个孩子并获取他们的退出状态,您需要采用不同的方法。wait仅当您知道哪个孩子已经死亡时,才能为您提供退出状态。
一种可能的方法是使用专用的命名管道来报告每个子项的状态。以下代码片段(未经测试!)返回最大的子级状态。
\n\nmkfifo status_pipe\nchildren=0\n{ child1; echo 1 $? >status_pipe; } & children=$((children+1))\n{ child2; echo 2 $? >status_pipe; } & children=$((children+1))\nmax_status=0\nwhile [ $children -ne 0 ]; do\n read -r child status <status_pipe\n children=$((children-1))\n if [ $status -gt $max_status ]; then\n max_status=$status\n fi\ndone\nrm status_pipe\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,如果其中一个子 shell 死亡且未报告其状态,则这将永远阻塞。在典型情况下不会发生这种情况,但如果手动终止子 shell,或者子 shell 内存不足,则可能会发生这种情况。
\n\n如果您想在其中一个子级失败时立即执行某些操作,请替换if [ $status -gt $max_status ]; then \xe2\x80\xa6为if [ $status -ne 0 ]; then \xe2\x80\xa6。