3

I have the idea of creating a control panel to monitor multiple scripts and processes. Having built the interface in advance, I seem to struggle with detecting the status of subprocess commands, getting a locked-up control panel as the child process has started.

There are methods such as subprocess.communicate() or subprocess.wait() to determine whether a process is alive/finished or not, yet those lock up the control panel for the lifetime of the child process. As seen in this block. the if clausule is never reached.

htop = subprocess.Popen(["xterm", "-e", "htop"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = htop.communicate():
if output:
    print("Succeeded!")
else:
    print("status unknown")

How would I be able to control and monitor the new process without locking up the control panel?

The idea is that the panel would be able to start/stop servers, and report on their status:

HTTP server status: running
DHCP server status: stopped

[1] start HTTP server 
[2] start DHCP server
[0] stop all servers

At the moment, it is possible to start a subprocess and see if it did by pressing [1]. It is not however possible to terminate the same subprocess with a different if-statement [0].

eymas
  • 105
  • 2
  • 15
  • `htop` is very explicitly meant to generate content for interactive viewing by humans. If you want to programatically inspect and interact with the process list, use the [`psutil`](https://pypi.org/project/psutil/) library. – Charles Duffy Mar 06 '19 at 13:46

2 Answers2

2

Use p.poll() or, if you need to check for output, use subprocess.PIPE for stdout and select() on p.stdout.

AKX
  • 152,115
  • 15
  • 115
  • 172
midor
  • 5,487
  • 2
  • 23
  • 52
  • True as far as it goes, but assumes that the OP's tool selection is fit-to-task (ie. that reading output from `htop` is a suitable way to track running processes). – Charles Duffy Mar 06 '19 at 13:47
  • one gripe is that I intend to implement this on a different process that has no static output string to read from (the stdout could be quite random). I've used `htop` as a way to get a persistent process, rather than something that exits upon success (such as `cat text.txt`) Hence why I think I should track the PID of the terminal that is being created, instead. – eymas Mar 06 '19 at 13:55
  • Seems like checking `poll` against `None` is good enough for you, then. I would not recommend to depend on `stdout` anyway. It can just be nice to forward output from subprocesses, if they have any. – midor Mar 06 '19 at 14:16
  • agreed, perhaps if I were to implement a log window in said control panel but so far I don't see the need for that since they would have their own terminal window either way. – eymas Mar 07 '19 at 09:49
0

I've found out how to control the subprocess via two if statements by making the process variable a global variable.

As a result, the code would be as follows (rough sketch):

if command == "run":
    global htop
    htop = subprocess.Popen(["xterm", "-e", "htop"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    if htop.poll() == None:
        htopStatus = "Running"
if command == "stop":
    if htop.poll() == None:
        htop.terminate()
        htopStatus = "Stopped"
eymas
  • 105
  • 2
  • 15