3

I am trying to create a program to easily handle IT requests, and I have created a program to test if a PC on my network is active from a list.

To do this, I wrote the following code:

self.btn_Ping.clicked.connect(self.ping)

def ping(self):
        hostname = self.listWidget.currentItem().text()
        if hostname:
            os.system("ping " + hostname + " -t")

When I run it my main program freezes and I can't do anything until I close the ping command window. What can I do about this? Is there any other command I can use to try to ping a machine without making my main program freeze?

user24343
  • 892
  • 10
  • 19
iMBLISH
  • 65
  • 2
  • 7
  • 1
    You can just run the `ping` command with the `-n 1` argument, so that only one attempt is made to contact the remote machine. The `-t` option you're using is supposed to "Ping the specified host until stopped." as per the documentation, so it's doing exactly what you asked of it. – hyperTrashPanda Feb 11 '19 at 10:42
  • You should avoid using `os.system`. Use `subprocess.call(["ping", hostname, "-t"])` instead. – Giacomo Alzetta Feb 11 '19 at 11:36
  • i want it to ping "for ever" or until canceled cause sometimes i am tracking a certain connection problem but i want it to be seperate from the main program – iMBLISH Feb 14 '19 at 09:00
  • If you want it to be separate, ``os.system`` is wronger. It waits for the command to complete. Don't use ``os.popen`` instead. – user24343 Feb 14 '19 at 21:29
  • actualy i played with threads and made a new thread something like this def ping_t1(host): _thread.start_new_thread(ping_t2,(host, )) – iMBLISH Feb 18 '19 at 08:59

3 Answers3

6

The docs state that os.system() returns the value returned by the command you called, therefore blocking your program until it exits.

They also state that you should use the subprocess module instead.

Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
0

From ping documentation:

ping /?

Options:
-t             Ping the specified host until stopped.
               To see statistics and continue - type Control-Break;
               To stop - type Control-C.

So, by using -t you are waiting until that machine has stopped, and in case that machine is not stopping, your Python script will run forever.

As mentioned by HyperTrashPanda, use another parameter for launching ping, so that it stops after one or some attempts.

Dominique
  • 16,450
  • 15
  • 56
  • 112
0

As mentioned in Tim Pietzcker's answer, the use of subprocess is highly recommended over os.system (and others).

To separate the new process from your script, use subprocess.Popen. You should get the output printed normally into sys.stdout. If you want something more complex (e.g. for only printing something if something changes), you can set the stdout (and stderr and stdin) arguments:

Valid values are PIPE, DEVNULL, an existing file descriptor (a positive integer), an existing file object, and None. PIPE indicates that a new pipe to the child should be created. DEVNULL indicates that the special file os.devnull will be used. With the default settings of None, no redirection will occur; the child’s file handles will be inherited from the parent.
-- docs on subproces.Popen, if you scroll down

If you want to get the exit code, use myPopenProcess.poll().

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
user24343
  • 892
  • 10
  • 19