防止 bash 脚本在命令错误后退出

防止 bash 脚本在命令错误后退出

我有一个执行命令的脚本,该命令输出多行文本:

qmicli -d /dev/cdc-wdm0 --nas-get-serving-system

其输出:

Registration state: 'registered'
    CS: 'detached'
    PS: 'detached'
    Selected network: 'unknown'
    Radio interfaces: '1'
            [0]: 'none'
    Data service capabilities: '0'
    Detailed status:
            Status: 'none'
            Capability: 'cs-ps'
            HDR Status: 'none'
            HDR Hybrid: 'yes'
            Forbidden: 'yes'

我想检查第一行引号中的字符串。如果该字符串等于“registered”,我想做点什么。所以最初,我将其放入我的脚本中:

qmicli -d /dev/cdc-wdm0 --nas-get-serving-system | grep "'registered'"
if [ $? -eq 0 ]; then
    #do stuff
fi

这是有效的,除了 qmicli 命令时不时地出错(它与外部设备连接,有时硬件在应该响应时没有响应)。当这种情况发生时,整个剧本就会崩溃。所以我对 qmicli 命令进行了或运算,true这样就不会出现错误:

qmicli -d /dev/cdc-wdm0 --nas-get-serving-system || true | grep "'registered'"

但现在,$?是总是0,所以我无法使用我设置的 if 条件。

是否有更好的方法来检查命令的多行输出中的字符串,同时在命令返回错误时阻止脚本退出?

答案1

我假设您set -e在脚本中具有或等效的内容,因此如果命令失败,它就会退出。

现在这是不惯用的:

some command
if [ $? -eq 0 ]; then ...

这是一种不必要的迂回做法:

if some command; then ...

如果语句的测试部分中的命令失败,则if不会触发set -e,因为这会破坏语句的要点if。从Bash 文档-e:

如果失败的命令是紧跟在 orwhile关键字之后的命令列表的一部分until、语句中测试的一部分、在 a或 列表if中执行的任何命令的一部分(最后一个或之后的命令除外)、任何命令中的命令的一部分,则 shell 不会退出。管道但最后一个,或者如果命令的返回状态与.&&||&&||!

所以如果你这样做:

if qmicli -d /dev/cdc-wdm0 --nas-get-serving-system | grep "'registered'"; then
    #do stuff
fi

qmicli失败不会触发set -e


(另外,我不认为是qmicli失败导致了问题——它的qmicli失败方式导致了grep命令失败,从而导致了问题。)

相关内容