区分陷阱功能中的 CHLD 子壳

区分陷阱功能中的 CHLD 子壳

我有这个 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。

所以我有两个问题:

  1. 有没有办法识别 foo 函数中正在退出的子 shell?
  2. 为什么我看到退出代码为 0,而它应该是 1 或 2?

答案1

不确定为什么函数中的$?和值不属于有问题的,但以下修复似乎可以通过在函数内部使用来解决该问题,如下所示:$!fooCHLDjobs -pfoo

#!/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"

相关内容