检查命令错误是否包含子字符串

sma*_*art 5 bash

我有很多bash命令.其中一些因各种原因而失败.我想检查一些错误是否包含子字符串.

这是一个例子:

#!/bin/bash

if [[ $(cp nosuchfile /foobar) =~ "No such file" ]]; then
    echo "File does not exist. Please check your files and try again."
else
    echo "No match"
fi
Run Code Online (Sandbox Code Playgroud)

当我运行它时,错误被打印到屏幕上,我得到"不匹配":

$ ./myscript
cp: cannot stat 'nosuchfile': No such file or directory
No match
Run Code Online (Sandbox Code Playgroud)

相反,我希望捕获错误并符合我的条件:

$ ./myscript
File does not exist. Please check your files and try again.
Run Code Online (Sandbox Code Playgroud)

如何正确匹配错误消息?

PS我找到了一些解决方案,您对此有何看法?

out=`cp file1 file2 2>&1`
if [[ $out =~ "No such file" ]]; then
    echo "File does not exist. Please check your files and try again."
elif [[ $out =~ "omitting directory" ]]; then
    echo "You have specified a directory instead of a file"
fi
Run Code Online (Sandbox Code Playgroud)

PSk*_*cik 7

我会这样做的

# Make sure we always get error messages in the same language
# regardless of what the user has specified.
export LC_ALL=C

case $(cp file1 file2 2>&1) in 
    #or use backticks; double quoting the case argument is not necessary
    #but you can do it if you wish
    #(it won't get split or glob-expanded in either case)
    *"No such file"*)
        echo >&2 "File does not exist. Please check your files and try again." 
        ;;
    *"omitting directory"*)
        echo >&2 "You have specified a directory instead of a file"
        ;;
esac
Run Code Online (Sandbox Code Playgroud)

这也适用于任何POSIX shell,如果您决定将bash脚本转换为POSIX shell(dash可能比它快得多bash),这可能会派上用场.

您需要第一次2>&1重定向,因为可执行文件通常会输出主要不用于进一步处理机器的信息stderr.您应该>&2重定向与echos 一起使用,因为您在那里输出的内容符合该类别.

  • 可能值得一提的是为什么 `2>&1` 有帮助 (2认同)