如何在使用-e调用的bash脚本中获取子命令的状态?

时间:2016-04-19 18:56:24

标签: bash

我想用-e选项编写一个bash脚本,因此它会在任何错误上停止,但是希望允许特定的行返回一个不同于零的错误代码并在逻辑中使用它:

#/bin/bash -e
do_something_and_return_errcode
if [ $? -eq 2 ]; then
    specific_stuff
fi

该脚本通常以do_something_and_return_errcode结尾。我可以通过

来避免
do_something_and_return_errcode || true

但这会使$?返回0而我无法使用$PIPESTATUS,因为这不是管道。

3 个答案:

答案 0 :(得分:2)

首先,使用.flowconfighighly error-prone,而不是普遍认同的良好做法。

那说,考虑一下:

set -e

另一种选择只是暂时禁用该标志:

err=0
do_something_and_return_errcode || err=$?

答案 1 :(得分:0)

使用Charles Duffy建议的解决方案:

https://stackoverflow.com/a/36727957/887539

留下这篇文章作为参考:

你可以管它,考虑下面的例子:

% cat pipetst.sh
#!/bin/bash
set -e
false | true
printf "Pipe: %d, exit: %d\n" "${PIPESTATUS[0]}" "$?"
% ./pipetst.sh
Pipe: 1, exit: 0

这是一个hack,不应该在生产代码中使用,我会更多地删除set -e并在需要时实现错误处理。

如果您需要输出转到stdout,您可以直接转到cat

(echo hello; exit 1) | cat

答案 2 :(得分:0)

您可以使用PIPESTATUS查看所有管道命令的返回状态。请参阅Bash手册页上的" Pipelines"和" PIPESTATUS"壳变量。如果最后一个命令始终成功,则脚本将不会因set -e而退出。

> cat /tmp/emptyfile | grep "sometext" | echo "OK"; echo ${PIPESTATUS[@]}
OK
cat: /tmp/emptyfile: No such file or directory
1 1 0
> touch /tmp/emptyfile
> cat /tmp/emptyfile | grep "sometext" | echo "OK"; echo ${PIPESTATUS[@]}
OK
0 1 0
> echo "Find sometext here" > /tmp/emptyfile
> cat /tmp/emptyfile | grep "sometext" | echo "OK"; echo ${PIPESTATUS[@]}
OK
0 141 0