我正在编写一个 shell 脚本,并尝试检查命令的输出是否包含某个字符串。我想我可能得用 grep 但我不知道怎么用。有人知道吗?
测试 grep 的返回值:
./somecommand | grep 'string' &> /dev/null if [ $? == 0 ]; then echo "matched" fi
按惯例是这样做的:
if ./somecommand | grep -q 'string'; then echo "matched" fi
还有:
./somecommand | grep -q 'string' && echo 'matched'
测试 $?是 反模式。
$?
另一个选项是检查命令输出上的正则表达式匹配。
例如:
[[ "$(./somecommand)" =~ "sub string" ]] && echo "Output includes 'sub string'"
一个干净的 if/else 条件 shell 脚本:
if (ls | grep '$1') then echo "exists" else echo "doesn't exist" fi
以上所有(非常优秀的)答案都假设 grep可以“看到”命令的输出,这并不总是正确的:
grep
SUCCESS 可以发送到 < strong > STDOUT ,而 失败可以发送到 STDERR 强 >。
因此,取决于您测试的方向,您的 grep可能会失败。也就是说,如果您正在测试 失败的情况,那么在这种情况下,您必须使用 2>&1将命令的输出重定向到 STDOUT。
2>&1
我使用 grep在 bash 脚本中进行了一个我认为非常简单的测试,结果一直失败。接着就是很多挠头的事情。使用 set -x在我的脚本显示,变量是空的!因此,我创建了以下测试来了解事情是如何破裂的。
set -x
注意 : iscsiadm是来自“ < strong > open-iscsi ”包的 Linux 工具,用于连接/断开主机到 SAN 存储。命令 iscsiadm -m session用于显示是否建立了任何 LUN 连接) :
iscsiadm
iscsiadm -m session
#!/bin/bash set -x TEST1=$(iscsiadm -m session) TEST2=$(iscsiadm -m session 2>&1) echo echo 'Print TEST1' echo $TEST1 echo echo 'Print TEST2' echo $TEST2 echo
如果连接了 LUN 曾经是,则两个变量都成功地填充了值:
Print TEST1 tcp: [25] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:ipdisk.Target-LUN1 (non-flash) tcp: [26] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:storagehost.Target-LUN1 (non-flash) Print TEST2 tcp: [25] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:ipdisk.Target-LUN1 (non-flash) tcp: [26] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:storagehost.Target-LUN1 (non-flash)
然而,如果一个 LUN abc2连接上了,abc0就会把输出发送到 STDERR,而且只有“ 测试2”变量被填充到我们使用 2>&1重定向到 STDOUT 的地方,而没有重定向到 STDOUT 的“ 测试1”变量是空的:
iscsiadm: No active sessions. Print TEST1 Print TEST2 iscsiadm: No active sessions.
如果您遇到类似这样的时髦的、半破碎的 只能朝一个方向工作,而不能朝另一个方向情况,请尝试使用您自己的命令替换 iscsiadm,您应该获得适当的可见性来重写测试以正确工作。