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
的返回。您可以设置一个陷阱。如果等待是最后一次,如图所示,则退出状态将是等待返回的任何状态