Reputation: 121
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
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
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