0

I am just trying to put together a simple server up/down script as I have just started to learn python.

Below is the script... but I can't get it to output the Server Down section of code. the if response == 0 I'm guessing is picking up the "Destination Unreachable" response and is making a false positive.

what can I do to get around this?

# Server up/down Script

import os

hostname1 = input (" Please Enter IP Address: ")

response = os.system("echo ping -a -c 1 " + hostname1)

#and then check the response...
if response == 0: # This will check the host repeatedly
    print (hostname1, '\033[1;32m [ **SERVER ALIVE** ] \033[1;m')
    # As long as the server is up it will print the UP response in green text
else:
    print(hostname1, '[ **SERVER DOWN** ]')
print( 30 * "-")
hnefatl
  • 5,860
  • 2
  • 27
  • 49
  • 1
    You're running `echo ping ...` in the shell, rather than `ping ...`, so the command is just going to print `"ping ..."` and exit with code 0. – hnefatl Nov 07 '18 at 23:55
  • Also as a general note on best-practices, one should use the techniques [here](https://stackoverflow.com/questions/35817/how-to-escape-os-system-calls) to ensure a script isn't vulnerable to injection (in case someone enters `;rm -rf $HOME` as the hostname). – hnefatl Nov 08 '18 at 00:04
  • Thank you for the help... ill pull echo out, I was just trying to get it to show the Print statement instead of all the ping replies – Alan Wolfe Nov 08 '18 at 00:37

1 Answers1

0
response = os.system("echo ping -a -c 1 " + hostname1)

The system command you are executing is just an echo, which will just print "ping -a -c 1 <hostname>" to stdout, and then return 0. It does not really do any pinging. You can test it by running the system commands directly on a terminal and checking the return value:

$ echo ping -a -c 1 8.8.8.8 
ping -a -c 1 8.8.8.8
$ echo $?  # returns 0
$ echo ping -a -c 1 <some.invalid.ip> 
<some.invalid.ip>
$ echo $?  # still returns 0

You should remove echo and just do:

response = os.system("ping -a -c 1 " + hostname1)

Which should return the correct result:

# VALID IP

>>> response = os.system("ping -a -c 1 8.8.8.8")
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=119 time=5.80 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 5.803/5.803/5.803/0.000 ms
>>> print(response)
0

# INVALID IP

>>> response = os.system("ping -a -c 1 5.5.5.5")
PING 5.5.5.5 (5.5.5.5) 56(84) bytes of data.

--- 5.5.5.5 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

>>> print(response)
256

For system calls, I recommend to use the subprocess package instead, which includes subprocess.run function that can print the command output and then return an object containing the command's return code.

# VALID IP

>>> response = subprocess.run(["ping", "-c", "1", "8.8.8.8"])
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=119 time=5.19 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 5.194/5.194/5.194/0.000 ms
>>> response.returncode
0

# INVALID IP

>>> response = subprocess.run(["ping", "-c", "1", "5.5.5.5"])
PING 5.5.5.5 (5.5.5.5) 56(84) bytes of data.

--- 5.5.5.5 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

>>> response.returncode
1

If you wanted to hide the output of the ping command, you can pass subprocess.PIPE to stdout of subprocess.run:

>>> response = subprocess.run(["ping", "-c", "1", "5.5.5.5"], stdout=subprocess.PIPE)
>>> response.returncode
1

The recommendation to use subprocess is noted in the os.system doc:

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function. See the Replacing Older Functions with the subprocess Module section in the subprocess documentation for some helpful recipes

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
  • @AlanWolfe It happens :) I saw your latest comment ("_I was just trying to get it to show the Print statement instead of all the ping replies_"), and I added info to my answer on how to make `subprocess.run` quiet. – Gino Mempin Nov 08 '18 at 00:43