1

I've searched extensively for this answer but it still seems to elude me. I'm trying to write a bash script that will check if multiple servers with ip:port are alive. As ping doesn't support different ports (AFAIK), I found a nifty python 1 liner which can integrate into bash:

portping() { python <<<"import socket; socket.setdefaulttimeout(1); socket.socket().connect(('$1', $2))" 2> /dev/null && echo OPEN || echo CLOSED; }

This creates a function portping that can be called from within the bash script, which I then want to use on a txt file that contains a list of hosts:

Contents of hosts.txt
myserver.host.com 3301
myserver.host.com 3302

I then want the bash script to read from hosts.txt two variables $ip and $port, portping those variables, then store the echoed result of either 'OPEN' or 'CLOSED' into a variable for further actions (send a pushbullet message telling me that the server is down).

while read ip port;
do
    echo "Checking if $ip port $port is alive"
    portping $ip $port # debug check to see if python function is actually working
    status = 'portping $ip $port' # herein lies my issue, how do I get the python functions echo output into the variable ?
    echo "$ip $port is $status"
    if [ "$status" == "CLOSED" ]
        then
        echo "Sending pushbullet notification"
        # pushbullet stuff;
    else
        echo "It's Alive!"
    fi
done < ${HOSTS_FILE}

However the output I'm getting is this:

$ ./pingerWithPython.sh hosts.txt
Using file hosts.txt
Checking if myserver.host.com port 3301 is alive
OPEN
status: Unknown job: =
myserver.host.com 3301 is
It's Alive!
Checking if myserver.host.com port 3302 is alive
CLOSED
status: Unknown job: =
myserver.host.com 3302 is
It's Alive!

Lies! It's not alive :) Clearly the issue is with the status = line. There must be a simple fix for this but I'm too n00b to figure it out!

theCheek
  • 27
  • 5
  • Either change the single quotes to backticks, or use `foo="$(execute_me arg1 arg2)"` syntax – Jameson Sep 21 '16 at 06:07
  • Your terminology is confused. `ping` doesn't support port numbers because it doesn't use a protocol which has them. If you want to try to connect over TCP to a particular port, look at e.g. `nc -z` (aka `netcat`). – tripleee Sep 21 '16 at 06:18
  • Offtopic, when you see that python does what you need; wouldn't it be more reasonable to write the whole thing as python script? – GhostCat Sep 21 '16 at 06:30
  • @triplee thanks will do some research on that – theCheek Sep 21 '16 at 07:05
  • @GhostCat Absolutely you are right, but as I am planning on writing a few more scripts I really wanted to nail this concept. – theCheek Sep 21 '16 at 07:06

2 Answers2

2

To get the result of a command in a variable, you need to use backticks (`) instead of simple quotes ('), or the $() idiom:

status=`portping $ip $port`

or

status=$(portping $ip $port)

without spaces around the equal sign

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Tried both as suggested by yourself and Jameson, but the output is still the same. Could it have something to do with the python declaration itself? – theCheek Sep 21 '16 at 06:13
  • Sorry missed the spaces comment - obviously I'm new to bash and it's pinnikitiness is something I'm learning slowly! Thanks for the help, its working now. – theCheek Sep 21 '16 at 07:04
2

Adding to Serge Ballesta's answer, don't put spaces around the = in assignments, since shells are space sensitive.

Ideally it should have been

status=$(portping $ip $port)
Community
  • 1
  • 1
Inian
  • 80,270
  • 14
  • 142
  • 161