简体   繁体   中英

If true false parameter from variable grep

the code:

 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

If i use 8.8.8.8 it works but when i change it for ip which is not responding like 29.0.0.0 the error occurs : "There is no PING command". What is wrong ?

if $C; then

Here the command $C and will be executed and it's return code decides which branch to take.

But what you really have is the output of a command and you want to check if it's empty or not.

Change it to:

if [[ -z $C ]]; then

-z checks if string is empty. If it's empty then no match for "100% packet loss" (ping passed).

From manual:

-z string
          True if the length of string is zero.
if [ -z "$C" ]; then

-z is zero length check, and $C is your variable. it's put in [] because that's an alias to the test command which returns true if the input is correct, or false otherwise.

You could also do

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

Which would do a more traditional check for an empty string.

If you're really sure of what you want you could also go as far as:

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

Which uses grep's -q flag to do the check for results for us.

The code following if is expected to be a list of commands, not a string. You need to explicitly test if the string has zero length or not; one way is to use

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

However, a better solution is to not check the output, but rather check the exit status of 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

Here, the -q option suppresses all output. You don't actually care about the line containing "100% packet loss"; you simply care if grep finds it or not.

This may be what you are looking for:

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

The if command runs another command and it treats a zero result code as true, and any other result code as false. This is why if is commonly used with the test command or the open bracket command, which is just another way to run test .

This also explains your original error. It was trying to run the output of ping as a command.

I think it's better to check if there's 0% packet loss. Sometimes you get a reply even if it's not exactly from 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM