我有以下内容,我认为它并行运行子 shell,但实际上似乎串行运行它们,我不明白为什么:
#!/usr/bin/env bash
set -e;
set -m # allow for job control
EXIT_CODE=0; # exit code of overall script
function handleJobs() {
for job in `jobs -p`; do
echo "PID => ${job}"
CODE=0;
wait ${job} || CODE=$?
if [[ "${CODE}" != "0" ]]; then
echo "At least one process failed with exit code => ${CODE}" ;
EXIT_CODE=1;
fi
done
}
trap 'handleJobs' CHLD
for file in "$HOME/mongodump_dev/cdt_db/"* ; do
file="$(basename "$file")"
if [[ "$file" != "system"* && "$file" != "locks"* ]]; then
mongorestore \
--db "cdt_dev" \
--collection "${file%.*}" \
--host "<my-host>" \
"$HOME/mongodump_dev/cdt_db/$file" &
fi;
done
wait;
echo "exit code => $EXIT_CODE"
exit "$EXIT_CODE"
有人知道为什么子shell 串联运行吗?
我尝试这样做:
(
mongorestore \
--db "cdt_dev" \
--collection "${file%.*}" \
--host "<my-host>" \
"$HOME/mongodump_dev/cdt_db/$file" &
) &
现在它们并行运行,但现在整个脚本永远不会退出,我担心我实际上没有准确捕获退出代码。
答案1
您编写的脚本存在许多“问题”。我所做的是复制您的脚本,并出于测试和评估的目的,通过执行诸如替换mongorestore
为 之类的操作sleep 9999
以及插入echo
附加到日志文件的跟踪消息来简化它。总而言之,在我看来你并不需要任何陷阱;只需将您的mongorestore
声明替换为:
( mongorestore ...
exit_code=$?
[ $exit_code -ne 0 ] \
&& printf "Process %s for file %s failed with exit code %s\n" \
$BASHPID "${file%.*}" $exit_code
) &
顺便说一句,验证所有子进程是否已并行生成的简单方法是打开另一个终端并运行pgrep -a mongorestore
.
另外,在我看来,在脚本末尾使用 EXIT_CODE 永远不应该有值,因此您的exit
命令应该因某种错误而失败,这意味着您的脚本总是会因错误而退出。