82

This is my python code:

import subprocess
subprocess.check_output("ls",shell=True,stderr=subprocess.STDOUT)

import subprocess
subprocess.check_output("yum",shell=True,stderr=subprocess.STDOUT)

The first .check_output() works well, but the second returns this:

Traceback (most recent call last):
File "/usr/lib/x86_64-linux-gnu/gedit/plugins/pythonconsole/console.py", line 378, in __run
r = eval(command, self.namespace, self.namespace)
File "<string>", line 1, in <module>
File "/usr/lib/python3.4/subprocess.py", line 616, in check_output
raise CalledProcessError(retcode, process.args, output=output)
subprocess.CalledProcessError: Command 'yum' returned non-zero exit status 1

Why does this happen? Is it because ls is the original shell command but yum is the new package? How can I solve this problem?

petezurich
  • 9,280
  • 9
  • 43
  • 57
Zongze Wu
  • 953
  • 1
  • 6
  • 8

2 Answers2

77

The command yum that you launch was executed properly. It returns a non zero status which means that an error occured during the processing of the command. You probably want to add some argument to your yum command to fix that.

Your code could show this error this way:

import subprocess
try:
    subprocess.check_output("dir /f",shell=True,stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
    raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
Plouff
  • 3,290
  • 2
  • 27
  • 45
  • 1
    so if i just want to implement command (g3-from-scratch.csh tpall.fna from-scratch) in python. This command will create some files in current directory but give not reply in console, i test this command in shell,it work. how could i implement it in python?originally,i use os.system(),but it just return (sh: 1: g3-from-scratch.csh: not found) – Zongze Wu Jan 13 '15 at 12:52
  • I try your code for yum, it work well, but not for g3-from-scratch.csh. I do not what is the different with them, I can use they directly in console. – Zongze Wu Jan 13 '15 at 13:00
  • 3
    why would you use `check_output()` if you are not using the captured output? – jfs Jan 13 '15 at 17:52
  • 1
    finally, i solve the problem, i should add abs path in front of g3-from-scratch.csh, because my environment path is relative path (~/software/glimmer3.02) but it should write (/home/username/software/glimmer3.02). – Zongze Wu Jan 13 '15 at 20:07
  • 1
    Downvote: This is a clumsy workaround. Don't call `check_output()` if you don't actually want Python to check the exit code and raise an error if it's not zero. See [jfs' anser elsewhere on this page](https://stackoverflow.com/a/27928363/874188) for details and a better approach. – tripleee Sep 18 '17 at 04:04
  • I'm not sure if I like the solution. This (the try/except) assumes the return state of the command, when not zero, to be an erroneous situation. That's by fare not always the case. I just want the return value (or the std output) and 'if not zero' we'll do something else. My point is a nonzero return might be a valid situation still. Liked the other answer better. – GerardJP Nov 09 '19 at 09:51
21

The word check_ in the name means that if the command (the shell in this case that returns the exit status of the last command (yum in this case)) returns non-zero status then it raises CalledProcessError exception. It is by design. If the command that you want to run may return non-zero status on success then either catch this exception or don't use check_ methods. You could use subprocess.call in your case because you are ignoring the captured output, e.g.:

import subprocess

rc = subprocess.call(['grep', 'pattern', 'file'],
                     stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
if rc == 0: # found
   ...
elif rc == 1: # not found
   ...
elif rc > 1: # error
   ...

You don't need shell=True to run the commands from your question.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • So you check the return code after the `subprocess.call` anyway. Is there a real case where you should use `call` instead of `check_output` apart from the scenario of command that has invalid return code? Thx! – Plouff Jan 13 '15 at 21:38
  • Exceptions should be raised in exceptional cases only (there are exceptions but the general rule holds). If you expect `grep` to return `1` (if it is not an error in your application) then you should not raise the exception. The exit status is checked to find out whether the pattern is found in the file: it is the whole point of running the child process in the first place. Also, you should not use `check_output()` unless you use its return value (the output from the subprocess) – jfs Jan 13 '15 at 21:58
  • Thank you for your explanations. I understand the idea with `grep` but it is still not that obvious for me. I just created a question: http://stackoverflow.com/q/27938050/882697 . Could you have a look? Thank you again! – Plouff Jan 14 '15 at 07:49