【发布时间】:2018-08-10 22:39:21
【问题描述】:
我尝试了多种不同的方法来检索后台进程的退出状态:
- 捕获每个后台进程的pid,存储在数组中然后等待每个PID,获取每个PID的返回状态并存储在STATUS数组中。
Con: pid 不是这个 shell 的子代
- tail --pid= -f /dev/null
Con:此处的退出状态始终为 0
在 stackoverflow 上四处寻找各种答案。我仍然无法让它工作。你能帮忙告诉我哪里出错了吗?
PIDS=()
STATUS=()
OVERALL_EXIT=0
# run processes and store pids in array
for target in ${target_list} ; do
./<script_to_execute> ${target} &
PIDS+=$!
done
# wait for all processes to finish and then capture return status of each
for pid in ${PIDS[@]}; do
echo "${pid}"
wait ${pid}
#tail —pid=${pid} -f /dev/null
#ps ax | grep ${pid} | grep -v grep
STATUS+=($?)
done
# looping through the status arr to check exit code for each
i=0
for st in ${STATUS[@]}; do
if [[ ${st} -ne 0 ]]; then
echo "$i failed"
OVERALL_EXIT=1
else
echo "$i finished"
fi
((i+=1))
done
exit ${overall_exit}
【问题讨论】:
-
PIDS+=( "$!" )。如果不使用括号,则将字符附加到列表的第一个元素,而不是添加额外的列表元素。并使用for pid in "${PIDS[@]}",带引号;通过shellcheck.net 运行您的代码 -
顺便说一句,这不是您的问题的原因,但请注意,全大写名称用于对 shell 有意义的变量,而带有小写字符的名称保证不会与 shell 的行为冲突。来自 POSIX 规范 @pubs.opengroup.org/onlinepubs/9699919799/basedefs/… -- 包含小写字母的环境变量名称的命名空间是为应用程序保留的。应用程序可以使用此名称空间中的名称定义任何环境变量,而无需修改标准实用程序的行为。
-
...阅读上述内容时,请记住,即使设置常规 shell 变量也会覆盖任何已存在的同名环境变量。
-
您现有的
wait "$pid"方法很好,如果您只是修复存储和检索 PID 的方式(正如我的回答向您展示的那样)。也许可以让它wait "$pid" || (( overall_exit |= $? ))来同时更新一个overall_exit变量,而不需要第二个循环。 -
让我再次强调一下 -- 以使先前答案无效的方式更改问题是违反这里的规则的。如果其他人无法理解并从问题中学习他们看不到答案的上下文。(见meta.stackoverflow.com/questions/295089/…)
标签: bash parallel-processing background-process exit-code