出现特定错误消息时重新运行命令

出现特定错误消息时重新运行命令

我正在运行一个可能会遇到错误的命令:

cmd sub-cmd --param1 value1 --param2 value2

该命令有可能返回错误。错误消息是一个特定的错误消息,以某个字符串结尾(开头不同,但结尾始终相同)。我正在寻找一个小的 shell 脚本代码来重试相同的命令,以防cmd返回以特定字符串结尾的错误消息一定次数(比方说 5 次)。另外,请注意cmd接受参数,我希望 shell 脚本能够将它得到的任何内容传递给我的cmd.如果错误消息不是我要查找的错误消息,则 shell 脚本应返回错误并停止 ( exit(1))。谢谢。

答案1

然后我们需要捕获命令的输出。如果我们可以捕获所有内容(或者只是忽略标准输出),这是最简单的:

#!/bin/bash
errormsg=$( cmd "$@" 2>&1 >/dev/null )
re="known error message$"
if [[ $errormsg =~ $re ]]; then
    echo "cmd failed with known message
fi

命令替换$(..)和其中的重定向捕获命令的标准错误输出,并将非错误输出重定向到/dev/null.然后我们将其与正则表达式进行比较,其中$末尾的 表示字符串的结尾。 (命令替换会删除所有尾随换行符,因此正则表达式不需要匹配这些换行符。)"$@"扩展到脚本的参数,将它们作为参数传递给cmd.

当然,我们需要一个循环来重复运行程序。命令替换的替代方法是使用临时文件来存储错误输出并随后查看它。这也使得命令的标准输出可见变得更加容易,所以让我们这样做:

#!/bin/bash
re="known error message$"

retries=0
max_retries=5
errorfile=$(mktemp)                       # temp file for the errors
trap 'rm "$errorfile"' EXIT               # remove the temp file on exit

while cmd "$@" 2> "$errorfile";           # run the command
      ret=$?;                             # save the exit code
      [[ $( < $errorfile ) =~ $re ]]; do  # check the output
    cat "$errorfile" >&2                  # print the errors to
                                          # the script's stderr, too

    retries=$((retries+1))                # retry a couple of times
    echo -n "cmd failed with known message"
    if [[ $retries -lt $max_retries ]]; then
        echo ", retrying."
    else
        echo ", exit."
        exit 1
    fi
done
cat "$errorfile" >&2
echo "cmd completed with status $ret";    # use saved exit code, since it might
exit "$ret"                               # have failed for other reasons

while cmd1; cmd2; do ...运行指令1一开始,然后运行指令2作为循环条件。)

在上面,我忽略了命令的实际退出状态,只查看输出。如果您想考虑退出状态,则需要更改脚本。

相关内容