我有一个执行命令的脚本,该命令输出多行文本:
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
:
如果失败的命令是紧跟在 or
while
关键字之后的命令列表的一部分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
命令失败,从而导致了问题。)