Biyau
Biyau

Reputation: 121

Python Popen.subprocess Exit status 0, but program exits immediately after subprocess completes sucessfully

I'm trying to view live output from a subprocess in real time. I tried several methods here, but they didn't work for me. Now I have method that works, but it causes my program to exit immediately after it successfully completed the subprocess. I get a return code of zero. The command is being run inside a FreeBSD jail (like chroot), and actually works, it just exits before finishing the rest of the program.

 import os, sys, subprocess

 DEVNULL = open(os.devnull, 'w')
 save = DEVNULL

 tick = re.escape("'")
 Jcmd = "jexec 1 sh -c '/usr/local/bin/aria2c --quiet=false -x 10 " + re.escape(links[1]) + tick
 proc = subprocess.Popen(Jcmd, shell=True)
 returncode = proc.wait()
 print "RETURN CODE: ", returncode
 sys.stdout = save
 print "THIS PRINT STATEMENT DOES NOT EXECUTE, PYTHON EXITS BEFORE"


OUTPUT:

Download Results:
gid   |stat|avg speed  |path/URI
======+====+===========+=======================================================
c28be0|OK  |       0B/s|/usr/local/MOUNTPOINTS/_DOWNLOADS/document.pdf

Status Legend:
(OK):download completed.
RETURN CODE:  0

Upvotes: 2

Views: 1783

Answers (2)

Biyau
Biyau

Reputation: 121

As @Kenny pointed out, I had redirected sys.stdout and my program was actually still doing stuff after the sys.stdout = save. I added this line after that to restore output to the screen, sys.stdout = sys.stdout. So here it all is:

import os, sys, subprocess

 # Next 2 lines not needed
 # DEVNULL = open(os.devnull, 'w')
 # save = DEVNULL

 tick = re.escape("'")
 Jcmd = "jexec 1 sh -c '/usr/local/bin/aria2c --quiet=false -x 10 " + re.escape(links[1]) + tick
 proc = subprocess.Popen(Jcmd, shell=True)
 returncode = proc.wait()
 print "RETURN CODE: ", returncode

 # Next 2 lines not needed
 #sys.stdout = save
 #sys.stdout = sys.__stdout__

 print "THIS PRINT STATEMENT DOES NOT EXECUTE, PYTHON EXITS BEFORE"

Upvotes: 1

Kenny Ostrom
Kenny Ostrom

Reputation: 5871

I think you meant to silence stdout during the execution of your other process, in order to prevent python output from mucking up the subprocess's output. However, that may have been unnecessary here, since your python code just waits, so it can't print anything anyway.

If you want to silence the python prints, then restore them, it would be more like this:

import os, sys
with open(os.devnull, 'w') as DEVNULL:
    save = sys.stdout # this is what you want to restore later
    sys.stdout = DEVNULL
    print "this prints to devnull (not really)"
    sys.stdout = save # restore the original sys.stdout

print "this prints to stdout"

Notice that save is just a temporary variable for the real sys.stdout, which you want to get back later.

Upvotes: 0

Related Questions