从命名管道捕获非零退出代码

时间:2018-11-23 17:02:52

标签: 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 despite the "command not found"!

2 个答案:

答案 0 :(得分:5)

您需要捕获后台进程的进程ID和wait才能设置正确的退出状态:

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

答案 1 :(得分:1)

如果您需要能够捕获错误并采取特定的行为,陷阱可以成为您的朋友。该代码会自行打印,因此我只在此处发布运行:

$: 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=$?; echo "$x@$0:$LINENO"; exit $x' err行。 它将x设置为最后一个错误代码,它将是触发它的任何内容。然后,它打印代码,文件名和当前正在执行的代码(在陷阱之前),并以错误代码退出程序。这实际上是在wait上触发的。导致它保释,然后继续底部的回声。

无论有没有set -eo pipefail,它都可以工作。