将stderr存储到变量中并在Bash中打印出来

时间:2017-03-27 09:37:47

标签: bash stderr

我需要将stderr(2>& 1)存储到变量中,然后回显它。

find $var -type f -exec file -b {} \; | sort 2>&1 | uniq -c

有时,当$ var是/ etc时,它会在权限下写入错误, 所以我需要检查 2>& 1 是否错误。

我无法使用临时文件

1 个答案:

答案 0 :(得分:1)

执行后需要捕获标准错误代码,因此在您的情况下使用管道|是不可行的。

例如......

#!/bin/bash
FAKEDIR="/this/dir/dont/exist"

#example one
ERRMSG=$(mkdir "$FAKEDIR" 2>&1)
ERRNO="$?"  # determine Error Code
if [ "$ERRNO" -ne 0 ]; then # If variable is Not Equal 0
    echo "Error: ${ERRNO} Message: ${ERRMSG}"
fi

#example two
find -type f -exec  "$FAKEDIR" -b "{} \;" | sort | uniq -c
ERRNO="$?"  # this is the error code of uniq only
if [ "$ERRNO" -ne 0 ]; then
    echo "Ths text will never be shown, even 'find' went wrong."
fi

# example three
FIND=$(find "$FAKEDIR" -type f -exec file -b "{} \;" 2>&1)
ERRNO="$?"  # determine Error Code
if [ "$ERRNO" -ne 0 ]; then
    echo "Error: ${ERRNO} Message: ${FIND}"
else
    echo "$FIND" | sort | uniq -c
    ERRNO="$?"
    if [ "$ERRNO" -ne 0 ]; then
        echo "uniq returned an error code: ${ERRNO}"
    fi
fi

exit "$ERRNO"

三个示例中的两个在执行后立即捕获错误代码。通过这种方式,您可以保存运行任何脚本。

有一些使用exectrap的高级方法。但是我认为这将在一开始就走得很远。

<强>增加:

要完成帖子,我想解释如何使用pipes进行错误处理。

错误消息仅通过通道2,因此如果您仍想使用管道,您可以将所有错误消息转储到/dev/null以完全忽略,您仍然可以通过一个名为trap的技巧。如果任何程序返回的错误代码不是0,则trap将触发。否则,管道后面的工具会处理错误消息。

示例:

#!/bin/bash
trap "echo 'Error received. Exit programm!' && exit 0" ERR
mkdir "/this/dir/dont/exist"
echo "This text will never be shown!"
exit 0

当mkdir返回错误代码时调用陷阱,此示例与管道类似。

trap "commands..." ERR
programm args 2>/dev/null | programm args 2>/dev/null | ...

为了使代码更小,您可以使用exec来减少编码......

exec 2>/dev/null
trap "commands..." ERR
programm args | programm args | ...

或者,如果您仍想保留邮件,则可以使用exec 2>&1。对于某些测试来说这是可以的,你需要编写更少的代码,但不建议大多数编码,请记住这一点。

您还应该知道何时宣布stdinstdoutstderr非常重要。每个命令都以某种方式使用通道。因此,在代码中的某处放置2>&1不会对您有所帮助。