Bash 如何使用SIGCHLD处理子级失败时的错误退出代码
我有一个shell脚本,它使一堆子进程在后台运行。如果其中任何一个失败,我想用Bash 如何使用SIGCHLD处理子级失败时的错误退出代码,bash,sh,Bash,Sh,我有一个shell脚本,它使一堆子进程在后台运行。如果其中任何一个失败,我想用kill--$$终止所有子进程和父进程 我试图在父进程中创建一个更简单的信号处理函数检查\u exit\u code(),看看它是否可以正常工作。每次子进程终止时都会使用trap和SIGCHLD信号调用它 #!/bin/sh set -o monitor function check_exit_code { if [ $1 -eq "0" ] then echo
kill--$$
终止所有子进程和父进程
我试图在父进程中创建一个更简单的信号处理函数检查\u exit\u code()
,看看它是否可以正常工作。每次子进程终止时都会使用trap
和SIGCHLD
信号调用它
#!/bin/sh
set -o monitor
function check_exit_code {
if [ $1 -eq "0" ]
then
echo "Success: $1"
else
echo "Fail: $1"
fi
}
trap "check_exit_code $?" SIGCHLD
mycommand1 &
mycommand2 &
mycommand3 &
...
wait
不幸的是,这只会返回Success:0
,即使mycommand#
失败并且其退出代码为2
,因此我将函数更改为以下内容
#!/bin/sh
set -o monitor
function check_exit_code() {
local EXIT_STATUS=$?
if [ "$EXIT_STATUS" -eq "0" ]
then
echo "Success: $EXIT_STATUS"
else
echo "Fail: $EXIT_STATUS"
fi
}
trap "check_exit_code" SIGCHLD
mycommand1 &
mycommand2 &
mycommand3 &
...
wait
这只返回
Fail:145
,而mycommand#
无法返回。我怀疑当我写$?
时,我收到了另一个命令的退出状态。有什么问题?您将如何修复它?第一次尝试的问题是check\u exit\u status$?
周围的双引号。在设置陷阱之前,外壳将$?
扩展为零,因此,SIGCHLD会触发检查退出状态0
,无论发生什么情况,因此持续的成功:0
输出
关于您的第二次尝试,在进入陷阱操作时,特殊参数?像往常一样保持最近管道的退出状态,在本例中为等待
。由于为SIGCHLD设置了陷阱,因此外壳会中断等待
并分配128 + 17(相当于SIGCHLD的数字)到?,在接收到该信号时
使用bash-5.1.4或更新版本,您可以实现如下所示的预期结果:
while true; do
wait -n -p pid
case $?,$pid in
( 0* ) # a job has exited with zero
continue ;;
( *, ) # pid is empty, no jobs left
break ;;
( * ) # a job has exited with non-zero
trap "exit $?" TERM
kill 0
esac
done