如果来自变量grep的true false参数

时间:2014-07-18 12:10:37

标签: bash

代码:

 for i in {1..5}
 do
    PING=`ping -nq -w5 -c1 8.8.8.8`
    C=`echo $PING | grep "100% packet loss"`

    if $C; then
            echo "ok"
    else
            echo "not connected"
    fi
 done

如果我使用8.8.8.8它可以工作,但当我更改为没有响应的像29.0.0.0这样的错误时,会发生错误:“没有PING命令”。有什么问题?

5 个答案:

答案 0 :(得分:4)

if $C; then

这里命令$C将被执行,它的返回代码决定采取哪个分支。

但你真正拥有的是一个命令的输出,你想检查它是否为空。

将其更改为:

if [[ -z $C ]]; then

-z检查字符串是否为空。如果它是空的,则不匹配" 100%丢包" (ping通过)。

来自手册:

-z string
          True if the length of string is zero.

答案 1 :(得分:2)

if [ -z "$C" ]; then

-z是零长度检查,$C是您的变量。它放在[]中,因为它是test命令的别名,如果输入正确则返回true,否则返回false。

您也可以

if [ "$C" = "" ]; then

哪个会对空字符串进行更传统的检查。

如果你真的确定自己想要的东西,你也可以去:

if grep -q "100% packet loss" <<<"$PING"; then
        echo "not connected"
else
        echo "ok"
fi

使用grep&#39; s -q标志来检查我们的结果。

答案 2 :(得分:2)

if之后的代码应该是命令列表,而不是字符串。您需要显式测试字符串是否为零长度;一种方法是使用

if [[ -z $C ]]; then
    # No output, so at least one packet got through
    echo "ok"
else
    echo "not connected"

但是,更好的解决方案是不检查输出,而是检查grep的退出状态。

if ping -nq -w5 -c1 8.8.8.8 | grep -q "100% packet loss"; then
    # All packets lost, no connection
    echo "not connected"
else
    echo "ok"
fi

此处,-q选项会抑制所有输出。您实际上并不关心包含&#34; 100%数据包丢失的行&#34 ;;你只关心grep是否找到它。

答案 3 :(得分:1)

这可能是您正在寻找的:

for i in {1..5}
do
    PING=`ping -nq -w5 -c1 8.8.8.8`

    if echo $PING | grep -q "100% packet loss"; then
            echo "ok"
    else
            echo "not connected"
    fi
done

if命令运行另一个命令,它将零结果代码视为true,将任何其他结果代码视为false。这就是为什么if通常与test命令或open括号命令一起使用的原因,这只是运行test的另一种方式。

这也解释了您的原始错误。它试图将ping的输出作为命令运行。

答案 4 :(得分:0)

我认为最好检查是否有0%的数据包丢失。有时你得到答复,即使它不完全是从8.8.8.8:

for I in {1..5}; do
    if ping -nq -w5 -c1 8.8.8.8 | fgrep -q ' 0% packet loss'; then
        echo ok
    else
        echo 'not connected'
    fi
done