从命名管道捕获非零退出代码
Capture non-zero exit code from named pipe
即使发送到命名管道的进程失败,以下玩具脚本 (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"!
您需要捕获后台进程的进程 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
如果您需要能够捕获错误并应用特定行为,陷阱可能是您的朋友。这段代码会自行打印,所以我在这里 post a 运行:
$: tst
+ trap 'x=$?; echo "$x@[=10=]:$LINENO"; exit $x' err
+ rm -f mypipe
+ mkfifo mypipe
+ pid=6404
+ cat mypipe
+ cat ./tst
#! /bin/env bash
set -x
trap 'x=$?; echo "$x@[=10=]:$LINENO"; exit $x' err
#set -eo pipefail
rm -f mypipe
mkfifo mypipe
cat [=10=] >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@[=11=]:$LINENO"; exit $x' err
行。
它将 x 设置为最后一个错误代码,这将是触发它的任何内容。然后它打印代码、文件名和当前正在执行的行号(在陷阱之前),并使用错误代码退出程序。这实际上在 wait
上触发。它导致它在继续底部的回声之前保释。
有或没有 set -eo pipefail
都可以。
即使发送到命名管道的进程失败,以下玩具脚本 (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"!
您需要捕获后台进程的进程 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
如果您需要能够捕获错误并应用特定行为,陷阱可能是您的朋友。这段代码会自行打印,所以我在这里 post a 运行:
$: tst
+ trap 'x=$?; echo "$x@[=10=]:$LINENO"; exit $x' err
+ rm -f mypipe
+ mkfifo mypipe
+ pid=6404
+ cat mypipe
+ cat ./tst
#! /bin/env bash
set -x
trap 'x=$?; echo "$x@[=10=]:$LINENO"; exit $x' err
#set -eo pipefail
rm -f mypipe
mkfifo mypipe
cat [=10=] >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@[=11=]:$LINENO"; exit $x' err
行。
它将 x 设置为最后一个错误代码,这将是触发它的任何内容。然后它打印代码、文件名和当前正在执行的行号(在陷阱之前),并使用错误代码退出程序。这实际上在 wait
上触发。它导致它在继续底部的回声之前保释。
有或没有 set -eo pipefail
都可以。