Python freezing on unexpected CL output with subprocess module
I am writing a script to get version numbers from command line programs by using their appropriate 'version' command line flag i.e. --version, -v etc. The program as a whole uses a regex to get just the actual version number from the text output and then compares it to various conditions of minimum required or maximum allowed version pulled from an xml conf file etc.
The script works perfectly until executing bzip2.
For most programs there is no issue with the following code:
args = 'cmd --version'
output = subprocess.getstatusoutput(args)
pretty cut and dry. However! If you try this with, say, bzip2 (and so far this is the only program I've had an issue with) ala 'bzip2 --ve开发者_StackOverflowrsion' python "freezes" and you must ctrl-C to break out with no output recorded of course.
I've tried various variations such as going the long route i.e.:
import subprocess
from subprocess import PIPE, STDOUT
proc = subprocess.Popen(args, stdout=PIPE, stderr=STDOUT)
while(True):
code = proc.poll()
if(code is not None):
break
line = proc.stdout.readline() # or even read()
etc.
Regardless of which method I use to extract the relevant text, Python always hangs after a certain point. I've tried .kill() at certain points to head off the locking event but to no avail.
It's just with bzip2 I think because for some reason it's still expecting input with the --version flag.
Any thoughts?
My bzip2 is not expecting input even with --version, and you can test that easily for yourself by just running the command.
This code works for me on Python 2.4-3.2:
import subprocess
from subprocess import PIPE, STDOUT
import sys
proc = subprocess.Popen(sys.argv[1:], stdout=PIPE, stderr=STDOUT)
while True:
line = proc.stdout.readline() # or even read()
while True:
line = proc.stdout.readline() # or even read()
if not line:
break
print(line)
code = proc.poll()
if(code is not None):
break
No hanging of any kind. I can even run vi foo.py
with it. Obviously that doesn't work very well as vi suddenly doesn't have a terminal to talk to, but I get no hanging. Doing :q!
will quite vi as usual. So if your bzip2 expects input, just input something and it will continue. If this works, then that is the problem.
The code:
import subprocess
from subprocess import STDOUT,PIPE
proc = subprocess.Popen(("bunzip2","--version"),stdout=PIPE,stderr=STDOUT)
data = proc.stdout.read()
print data
now works with bzip2 1.0.6 (or bunzip2 1.0.6 but they're the same application). That really looks like a bug in bzip2 to me... --version should print version and quit, not try to read/write to stdin.
精彩评论