让我们将此视为一个起点:
#!/bin/bash
set -e
echo "Sleeping..."
sleep 2 &
wait
echo "Done"
exit 0
如果后台进程退出并出错,我希望wait
退出整个脚本。引入错误:
#!/bin/bash
set -e
echo "Sleeping..."
sleep SOMETHING_STRANGE_AND_WRONG &
wait
echo "Done"
exit 0
回显“完成”。我期待wait
退出脚本,因为set -e
。
我知道我可以保存pid
的{{1}}并以这种方式检查后台流程的返回值:
sleep
然而,当我在我的脚本中有几个这样的“同步点”时,这会很麻烦,而且在这些点中有几个子进程要等待。
我对错误代码本身不是很感兴趣,只是说它们没有成功。
如果等待的任何子进程没有成功,是否有一种不那么冗长的方式使#!/bin/bash
set -e
echo "Sleeping..."
sleep SOMETHING_STRANGE_AND_WRONG &
pid=$!
if wait $pid; then
echo "Success"
else
echo "Failure!"
exit 1
fi
echo "Done"
exit 0
失败并退出(因为wait
)?
编辑:我正在寻找set -e
失败的解决方案,如果任何的子流程失败,则退出:
wait
我目前以这种方式解决(我发现这很麻烦):
#!/bin/bash
set -e
echo "Sleeping..."
sleep SOMETHING_STRANGE_AND_WRONG &
sleep 2 &
wait
echo "Done"
exit 0
答案 0 :(得分:1)
缩短
wait || exit $?
或者如果需要消息,如果还没有通过失败的过程记录
wait || { echo "background failed: $?" >&2; exit 1;}
可以使用或函数
exit_fail() {
echo "$1" >&2
exit 1
}
...
wait || exit_fail "background failed: $?"
答案 1 :(得分:0)
我在一个函数中手动实现了这个功能。
# Wait for subprocesses with pids passed as arguments, exit if any failed.
# $1 info_string: to show the command that the failure/success relates to.
# $* list of pids to wait for and check.
wait_and_check () {
info_string=$1
shift
for p in $*; do
if wait $p; then
echo "$info_string process $p success"
else
echo "$info_string process $p Failure!"
exit 1
fi
done
}
用法:
pids=""
for p in $bunch_of_stuff ; do
stuff_function $p &
pids+=" $!"
done
wait_and_check "stuff" $pids
这感觉很多人应该有类似的东西,所以我很惊讶没有现成的解决方案。
一个缺点是很难检查进程的错误代码。