Bash 从命名管道捕获非零出口代码
即使发送到指定管道的进程失败,以下玩具脚本(Bash 从命名管道捕获非零出口代码,bash,named-pipes,exit-code,Bash,Named Pipes,Exit Code,即使发送到指定管道的进程失败,以下玩具脚本(tmp.sh)也会以代码0退出。如何从命名管道捕获非零出口代码?或者更一般地说,事情出了差错 #!/bin/bash set -eo pipefail mkfifo mypipe FOOBAR > mypipe & cat mypipe 运行并检查退出代码: bash tmp.sh tmp.sh: line 6: FOOBAR: command not found echo $? # <- Exit code is 0
tmp.sh
)也会以代码0退出。如何从命名管道捕获非零出口代码?或者更一般地说,事情出了差错
#!/bin/bash
set -eo pipefail
mkfifo mypipe
FOOBAR > mypipe &
cat mypipe
运行并检查退出代码:
bash tmp.sh
tmp.sh: line 6: FOOBAR: command not found
echo $? # <- Exit code is 0 despite the "command not found"!
bash tmp.sh
tmp.sh:第6行:未找到FOOBAR:命令
echo$?# 您需要捕获后台进程的进程id并等待它设置正确的退出状态:
#!/bin/bash
set -eo pipefail
rm -f mypipe
mkfifo mypipe
FOOBAR > mypipe &
# store process id of above process into pid
pid=$!
cat mypipe
# wait for background process to complete
wait $pid
现在,当您运行它时:
bash tmp.sh
tmp.sh: line 6: FOOBAR: command not found
echo $?
127
如果您需要能够捕捉错误并应用特定行为,那么陷阱可以是您的朋友。这段代码会自动打印,所以我只在这里发布一个运行:
$: tst
+ trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
+ rm -f mypipe
+ mkfifo mypipe
+ pid=6404
+ cat mypipe
+ cat ./tst
#! /bin/env bash
set -x
trap 'x=$?; echo "$x@$0:$LINENO"; exit $x' err
#set -eo pipefail
rm -f mypipe
mkfifo mypipe
cat $0 >mypipe &
pid=$!
cat mypipe
wait $pid
fubar >mypipe &
pid=$!
cat mypipe
wait $pid
echo done
+ wait 6404
+ pid=7884
+ cat mypipe
+ fubar
./tst: line 16: fubar: command not found
+ wait 7884
++ x=127
++ echo 127@./tst:19
127@./tst:19
注意trap'x=$?;回显“$x@$0:$LINENO”;退出$x'错误
行。
它将x设置为最后一个错误代码,不管触发它的是什么。然后它打印代码、文件名和当前正在执行的行号(在陷阱之前),并带着错误代码退出程序。这实际上是在等待时触发的。在继续底部的回声之前,它会使其脱落
它可以使用或不使用set-eo pipefail
如果它不是脚本中的最后一个命令,则需要显式捕获/处理wait
的返回。您可以设置一个陷阱。如果等待是最后一次,如图所示,则退出状态将是等待返回的任何状态