bash-根据过程条件返回值

时间:2018-09-17 09:51:23

标签: linux bash

我迷惑地发现了基于变量有条件地返回值的方法。我想检查过程是否成功,然后回显“过程成功”,但是如果失败,我想检查特定的错误消息,然后返回错误消息,

ERRMSG="$(cd /nonexist 2>&1)"
if [ $? -ne 0 ]
then
    if [ -z "$ERRMSG|grep -o 'No such file or directory'|head -1" ]
    then
    echo "empty" >> $FQLOGNAME
    else
    echo $ERRMSG|grep -o 'No such file or directory'|head -1 >> $FQLOGNAME
    fi
else
echo "success" >> $FQLOGNAME
fi

请咨询, 谢谢

2 个答案:

答案 0 :(得分:1)

您不需要使用grep来检查字符串是否包含子字符串。 Bash中的内置模式匹配就足够了。这段代码应该可以完成您想要的事情:

if ERRMSG=$(cd /nonexist 2>&1) ; then
    echo 'process success'
elif [[ $ERRMSG == *'No such file or directory'* ]] ; then
    echo 'No such file or directory'
else
    echo 'empty'
fi >> "$FQLOGNAME"

有关[[...]]的模式匹配功能的详细信息,请参见Conditional Constructs section of the Bash Reference Manual

我保留了ERRMSGFQLOGNAME变量,但是请注意,最好避免使用ALL_UPPERCASE变量名。它们有可能与环境变量或Bash内置变量发生冲突。参见Correct Bash and shell script variable capitalization

要在多行错误消息中查找由模式定义的错误消息,并且仅打印第一个错误消息,可以在=~中使用正则表达式匹配([[...]])。为了提供一个具体的示例,此代码假定错误消息由“ ERROR”,后跟一个或多个空格,后跟一个十进制数字组成:

# Example function for testing
function dostuff
{
    printf 'Output line A\n'
    printf 'Encountered ERROR 29\n' >&2
    printf 'Output line B\n'
    printf 'Encountered ERROR 105\n' >&2
    printf 'Output line C\n'

    return 1
}

# Regular expression matching an error string
readonly error_rx='ERROR +[0-9]+'

if ERRMSG=$(dostuff 2>&1) ; then
    echo 'process success'
elif [[ $ERRMSG =~ $error_rx ]] ; then
    printf '%s\n' "${BASH_REMATCH[0]}"
else
    echo 'empty'
fi >> "$FQLOGNAME"

它将'ERROR 29'附加到日志文件。

有关Bash内置正则表达式匹配的更多信息,请参见mklement0's answer to "How do I use a regex in a shell script?"

答案 1 :(得分:0)

使其更简单,更容易:

if ! ERRMSG=$(cd /nonexist 2>&1); then
     if <<<"$ERRMSG" grep -q 'No such file or directory'; then
           # if the error string contains the message 'No such file or directory'
           echo "empty" >> "$FQLOGNAME"
     else
           printf "Unhandled cd error: %s" "$ERRMSG" >> "$FQLOGNAME"
     fi
else
     echo "process success" >> "$FQLOGNAME"
fi
  1. if语句检查COMMAND的返回状态。 [test只是一个返回状态的命令。赋值的返回状态与命令状态相同。我的意思是out=$(cmd); if [ "$?" -eq 0 ]; thenif out=$(cmd); then相同。
  2. 使用HERE字符串比echo "$string"更好。 Echo并没有那么可移植,最好习惯于printf "%s" "$string"这是一种可移植的方式。但是,HERE字符串在流的末尾添加了额外的EOF,有时会中断while read循环,但在大多数情况下都可以。
  3. 不要if [ -z "$(echo smth | grep ..)" ]; then。您只需检查if echo smth | grep ...; then或使用HERE字符串if <<<"smth" grep -q ...; thenif grep -q ... file; then即可查看grep返回状态。具有-q--quiet替代项的--silent选项使grep不产生输出。
  4. 从单个命令替换中分配变量时,不需要引用。 tmp="$(...)"tmp=$(...)相同。