0

I'm making a small script to determine if I have an internet connection on OSX. More of just practice, I suppose.

In terminal "ifconfig | grep -cs 'status: active' " will return 1 if there's at least one active connection

The script I have is this

    #!/bin/bash

detect(){
ONLINE=ifconfig | grep -cs 'status: active'
}

if [[ detect = 1 ]]
then
        echo "Online"
else
        echo "Offline"
fi

However the Variable ONLINE always returns 0. From what I can tell/understand, this has to do with using a pipe inside of the script. A sub-pipe is used when running the command, and ONLINE just gets stuck with 0 as the sub-pipe closes.

I think I see the issue, but I don't know how to get around this. I saw a bunch of work arounds for scripts having this issue with while loops, but nothing where I need the output from ifconfig fed into grep.

4 Answers4

2

Several problems with your current script:

  1. You set a variable ONLINE, but you test for detect.
  2. You don't actually assign the result of the ifconfig | grep -cs 'status: active' command to the variable ONLINE
  3. You use = instead of == to test for equality

The following would seem to be closer to what you intended:

#!/bin/bash
ONLINE=$(ifconfig | grep -cs 'status: active')
if [[ $ONLINE == 1 ]]
then
  echo "online"
else
  echo "offline"
fi
Floris
  • 45,857
  • 6
  • 70
  • 122
  • `Point 2` is incorrect. The string `ifconfig` is assigned to the variable `ONLINE`, not any result. – Samveen Sep 04 '13 at 10:43
  • @Samveen - thanks for pointing out my mistake - although the code as written does not result in the value `ifconfig` for `ONLINE` either... I have updated my answer to be more accurate. – Floris Sep 04 '13 at 18:14
  • As the assignment is made in the same line as a command, it is ephemeral. See my answer below for details. Also you need to explain that subroutines do not return values in bash, just exit status, thus capturing variables from subroutine calls needs the subroutine to echo it's expected return value and it's call needs an assignment with command substitution – Samveen Sep 05 '13 at 03:18
1

use this:

ONLINE=$(ifconfig | grep -cs 'status: active')


cause without "$" what bash will return is the result of the command being successful or not and if it is successful it is always zero.

Soosh
  • 812
  • 1
  • 8
  • 24
0

Or you can just keep it simple like this ...

ifconfig | grep 'status: active' > /dev/null 2>&1
if [ $? == 0 ]
then
   echo "online"
else
   echo "offline"
fi
Red Cricket
  • 9,762
  • 21
  • 81
  • 166
-1

As none of the answers explain the exact issue with your script, I'm adding an answer.

The issue lies with the line ONLINE=ifconfig | grep -cs 'status: active'.

What is wrong is that there is no command substitution ($(...) or `...`) used in the line. As correctly suggested by other answers as well, the assignment needs to be $(ONLINE=ifconfig | grep -cs 'status: active').

What this line actually does is that it assigns the string "ifconfig" to the variable ONLINE and pipes the output of that (no output in this case) through grep -cs ...

One point to note is that this assignment is only for the duration of that line, and does not survive till the next line. To illustrate:

samveen@precise:~$ I=0
samveen@precise:~$ echo $I
0
samveen@precise:~$ I=1 | echo "blank"
blank
samveen@precise:~$ echo $I
0

Edit: I totally missed another very important point: Subroutines do not return values in bash, just exit status

Thus capturing variables from subroutine calls needs the subroutine to echo it's expected return value and it's call needs an assignment with command substitution.

Something like this:

detect(){
    ONLINE=$(ifconfig | grep -cs 'status: active')
    echo $ONLINE
}

if [[ $(detect) -eq 1 ]]
then
    echo "Online"
else
    echo "Offline"
fi

Also, use -eq to test numeric equality.

Finally, the shortest way to do what you want is

ifconfig | grep -q 'status:active' && echo "online" || echo "offline"
Samveen
  • 3,482
  • 35
  • 52