0

Here's the context: I am using python 2.7.5. And I would like to run UNIX commands as well as maven commands in a python script. I was successful to do so, using os.system("cmd"), but I need to work on the result of the given command. After reading the doc and some threads in here, I decided to use the subprocess module to redirect the output to the stdout using PIPE. Unexpectedly, I am getting an OSError as shown in the attached image. Your help will be much appreciated. In addition to the given sample in the attached image, I have tried:

p = os.popen("java -version")
result = subprocess.check_output(p, shell=True)
subprocess.call("ls /usr", shell=True)
p.s. Using shell=True is strongly discouraged (doc), since it can be dangerous when coupled with unsanitized input. 

Also, I took a look at the given script in the error message /usr/lib64/python2.7/subprocess.py, line 711 adn 1327 but didn't learn more than what is mentionned in the error message: raise child_exception Subprocess Terminal Output

1 Answer 1

1

You aren't using subprocess.check_output correctly. You're trying to pass a pipe file object (the return value of os.popen) to check_output but it's expecting a command argument or argument vector.

Also, the subprocess.call function won't capture the executed command's output, so you would only use that if you want the output of ls /usr (or whatever) to be seen by the user running the script interactively. (Which is pretty much the same as os.system.)

Try this instead (showing with and without the shell):

import subprocess

out1a = subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT)
print(out1a)

out1b = subprocess.check_output('java -version', stderr=subprocess.STDOUT, shell=True)
print(out1b)

out2a = subprocess.check_output(['ls', '/usr'])
print(out2a)

out2b = subprocess.check_output('ls /usr', shell=True)
print(out2b)

# Cannot capture output this way, but it will be visible to user
subprocess.call('ls /usr', shell=True)

Note that in the case of the java -version command, the version info gets printed to the command's standard error output so you must redirect that in order to capture it as the returned value of check_output (hence the stderr=subprocess.STDOUT).

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, Gil. the command out1a and its printing is working now. But how could I fextract first line, since I want to check if the version match a certain number? I have tried to redirect the output to a file.txt but not working. Is there a command that helps to extract and work directly with the terminal output?
The result you get back is a string containing multiple lines of text. Use out1a.splitlines() to decompose that into individual lines. That returns a tuple from which you can select components you care about. Try, for example, print(out1a.splitlines()[0]). Then use other string methods to isolate the version number you need (see docs.python.org/2/library/…)
Alright, that helped me solve my problem. Again, thanks Gil. Here's how I completed: import subprocess import re res = subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT) res2 = res.splitlines()[0].split()[2] versionNumber = re.findall('[0-9._]+', res2) print(versionNumber) if versionNumber[0] >= 1.7: print "Cool" else: print "Install a newer version"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.