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

Dan*_*aks 8 grep shell-script

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

qmicli -d /dev/cdc-wdm0 --nas-get-serving-system
Run Code Online (Sandbox Code Playgroud)

输出:

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'
Run Code Online (Sandbox Code Playgroud)

我想检查第一行引号中的字符串。如果字符串等于 'registered',我想做点什么。所以最初,我把它放在我的脚本中:

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

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

qmicli -d /dev/cdc-wdm0 --nas-get-serving-system || true | grep "'registered'"
Run Code Online (Sandbox Code Playgroud)

但是现在,$? 是总是0,因此,如果有条件我已经建立了我不能使用。

有没有更好的方法来检查命令的多行输出中的字符串,但如果命令返回错误,还可以防止脚本退出?

mur*_*uru 11

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

现在这是单调的:

some command
if [ $? -eq 0 ]; then ...
Run Code Online (Sandbox Code Playgroud)

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

if some command; then ...
Run Code Online (Sandbox Code Playgroud)

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

如果失败的命令是紧跟在命令列表的一部分shell不会退出whileuntil关键字在测试中,部分if声明,在执行任何命令的一部分&&||以下的最终除了命令列表&&||在任何命令一个管道但最后一个,或者如果命令的返回状态正在被!.

所以如果你这样做:

if qmicli -d /dev/cdc-wdm0 --nas-get-serving-system | grep "'registered'"; then
    #do stuff
fi
Run Code Online (Sandbox Code Playgroud)

qmicli失败不会触发set -e


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