theCheek theCheek - 2 months ago 11
Linux Question

Call a python process inside bash, then capture output into a variable

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!

Answer

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