我有这个 bash 脚本:
#!/usr/bin/env bash
set -m # allow for job control
EXIT_CODE=0 # exit code of overall script
function foo() {
echo "CHLD pid is $!" # doesn't seem to be the expected pid
echo "CHLD exit code is $?" #exit code seems to pertain to some other process
if [[ $? > 0 ]]; then
echo "at least one test failed"
EXIT_CODE=1
fi
}
trap 'foo' CHLD
DIRN=$(dirname "$0")
commands=(
"echo 'foo'; exit 1;"
"echo 'bar'; exit 0;"
"echo 'baz'; exit 2;"
)
clen=`expr "${#commands[@]}" - 1` # get length of commands - 1
for i in `seq 0 "$clen"`; do
(echo "${commands[$i]}" | bash) & # run the command via bash in subshell
echo "$i ith command has been issued as a background job"
done
# wait for all to finish
wait
echo "EXIT_CODE => $EXIT_CODE"
exit "$EXIT_CODE"
多个子 shell 退出,并在退出时触发 foo 函数。我原本预计 foo 函数只会捕获 3 个 CHLD 事件,但实际上至少有 6 个。
如何区分函数CHLD
中出现的事件foo
?
例如,以下是上述脚本的输出:
CHLD exit code is 0
CHLD exit code is 0
CHLD exit code is 0
0 ith command has been issued as a background job
1 ith command has been issued as a background job
2 ith command has been issued as a background job
bar
baz
foo
CHLD exit code is 0
CHLD exit code is 0
CHLD exit code is 0
EXIT_CODE => 0
如您所见,有 6 个CHLD
事件;但我真的只关心 3。此外,我应该将 1,0,2 视为退出代码,而不是 0,0,0。
所以我有两个问题:
- 有没有办法识别 foo 函数中正在退出的子 shell?
- 为什么我看到退出代码为 0,而它应该是 1 或 2?
答案1
不确定为什么函数中的$?
和值不属于有问题的,但以下修复似乎可以通过在函数内部使用来解决该问题,如下所示:$!
foo
CHLD
jobs -p
foo
#!/usr/bin/env bash
set -m # allow for job control
EXIT_CODE=0 # exit code of overall script
function foo() {
for job in `jobs -p`; do
echo "PID => ${job}"
if ! wait ${job} ; then
echo "At least one test failed with exit code => $?" ;
EXIT_CODE=1;
fi
done
}
trap 'foo' CHLD
DIRN=$(dirname "$0")
commands=(
"{ echo 'foo' && exit 4; }"
"{ echo 'bar' && exit 3; }"
"{ echo 'baz' && exit 5; }"
)
clen=`expr "${#commands[@]}" - 1` # get length of commands - 1
for i in `seq 0 "$clen"`; do
(echo "${commands[$i]}" | bash) & # run the command via bash in subshell
echo "$i ith command has been issued as a background job"
done
wait # wait for all to finish
echo "EXIT_CODE => $EXIT_CODE"
exit "$EXIT_CODE"