1

i am trying to get the output of a command in my python program by using "check_output" method. but i'm getting this error:

   out = check_output(command5 , shell=True)

File "/usr/lib64/python3.6/subprocess.py", line 336, in check_output **kwargs).stdout File "/usr/lib64/python3.6/subprocess.py", line 418, in run output=stdout, stderr=stderr) subprocess.CalledProcessError: Command 'oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_rht-ccp --results-arf arf.xml /usr/share/xml/scap/ssg/content/ssg-centos7-ds.xml' returned non-zero exit status 2.

this is the part of my program that is related:

command4 = "oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_rht-ccp --results-arf arf.xml /usr/share/xml/scap/ssg/content/ssg-centos7-ds.xml"
out = check_output(command4 , shell=True)

I am sure that the command is alright because I get the results when I write:

subprocess.call(command5,shell=True)

I am using python 3.6, and work in centos 7.

any idea why the check_output can not get the result?

afsane
  • 117
  • 3
  • 11
  • 1
    Because the command exited with a nonzero exit status, which indicates it failed. `check_call` and `check_output` raise `CalledProcessError` if that happens. – Daniel Pryden Oct 12 '18 at 15:58
  • Thank you @DanielPryden , but why "nonzero exit status" happens? how can i fix it? – afsane Oct 12 '18 at 16:02
  • 1
    @afsane: that's up to that command to tell you. Look at the stderr output it produces, if any, and read the command documentation. – Martijn Pieters Oct 12 '18 at 16:02

1 Answers1

2

This is entirely normal, because the command you ran produced a non-zero exit code. It means that the command you ran is signalling that something may be wrong.

See the subprocess.check_output() documentation:

If the return code was non-zero it raises a CalledProcessError.

and

This is equivalent to:

run(..., check=True, stdout=PIPE).stdout

where the check=True flag tells run() to raise an exception when return_value is not 0:

If check is true, and the process exits with a non-zero exit code, a CalledProcessError exception will be raised.

The other function you used, subprocess.call(), does not set check=True:

Run the command described by args. Wait for command to complete, then return the returncode attribute.

This is equivalent to:

run(...).returncode

So either don't use check_output(), or catch the exception thrown, or fix the command you are running. That call() worked is no indication that the process actually produced a successful result.

For example, you could use subprocess.run() directly:

proc = subprocess.run(
    command5, shell=True, text=True
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if proc.returncode:
    print(f'Issue reported, exit code {proc.returncode}, stderr:')
    print(proc.stderr)
else:
    print(proc.stdout)
Alex Waygood
  • 6,304
  • 3
  • 24
  • 46
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thank you @MartijnPieters , First I should use "check_output" i need the results in my program, when I use "call()" it also have 2 warning, Do you think, it could be the problem? – afsane Oct 12 '18 at 16:10
  • could you please tell me exactly how can I "fix the command"? – afsane Oct 12 '18 at 16:17
  • 1
    @afsane: I don't know, I am not familiar with the command. I don't know what the exit code is or what that would mean. – Martijn Pieters Oct 12 '18 at 16:18
  • Ok, Thanks anyway. – afsane Oct 12 '18 at 16:20
  • @afsane: the [manpage I found](https://linux.die.net/man/8/oscap) states: *oscap returns 0 if all rules pass. If there is an error during evaluation, the return code is 1. If there is at least one rule with either fail or unknown result, oscap-scan finishes with return code 2.* So look at the specific exit code given. Perhaps use `subversion.run()` and do not set `check=True`. – Martijn Pieters Oct 12 '18 at 22:32
  • how can i not set "check=True"? – afsane Oct 13 '18 at 07:28
  • @afsane: by using `subprocess.run()` directly and not use `subprocess.check_output()`. – Martijn Pieters Oct 13 '18 at 08:35
  • yeah i am sorry you said that before but i need the results, because i want to pass them to server through socket. may be I should change the command. – afsane Oct 13 '18 at 13:48
  • @afsane: `subprocess.run()` gives you access to the results. That's what the code in my answer shows: `proc = subprocess.run(..., stdout=subprocess.PIPE, ...)`, then `proc.stdout`. – Martijn Pieters Oct 13 '18 at 13:58