이 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"
여러 하위 쉘이 종료되어 종료 시 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개만 관심이 있습니다. 또한 0,0,0이 아닌 1,0,2를 종료 코드로 간주해야 합니다.
그래서 두 가지 질문이 있습니다.
- foo 함수 내에서 종료되는 서브쉘을 식별하는 방법이 있습니까?
- 1 또는 2여야 하는 종료 코드가 0으로 표시되는 이유는 무엇입니까?
답변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"