Reputation:
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.
Upvotes: 0
Views: 6426
Reputation: 3540
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"
Upvotes: -1
Reputation: 46375
Several problems with your current script:
ONLINE
, but you test for detect
.ifconfig | grep -cs 'status: active'
command to the variable ONLINE
=
instead of ==
to test for equalityThe 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
Upvotes: 2
Reputation: 10470
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
Upvotes: 0
Reputation: 812
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.
Upvotes: 1