web-dev-qa-db-ja.com

サブプロセスがCalledProcessError例外を発生させたときのコマンドのリターンコードを確認します

python(3)スクリプトでシェルコマンドのstdoutストリームをキャプチャし、同時にシェルのリターンコードをチェックできるようにしたいエラーを返す場合(つまり、戻りコードが0でない場合)。

subprocess.check_outputはこれを行う適切な方法のようです。 subprocessのmanページから:

check_output(*popenargs, **kwargs)
    Run command with arguments and return its output as a byte string.

    If the exit code was non-zero it raises a CalledProcessError.  The
    CalledProcessError object will have the return code in the returncode
    attribute and output in the output attribute.

それでも、失敗した場合、シェルコマンドからリターンコードを取得することに成功しません。私のコードは次のようになります。

import subprocess
failing_command=['ls', 'non_existent_dir']

try:
    subprocess.check_output(failing_command)
except:
    ret = subprocess.CalledProcessError.returncode  # <- this seems to be wrong
    if ret in (1, 2):
        print("the command failed")
    Elif ret in (3, 4, 5):
        print("the command failed very much")

このコードは、例外自体の処理で例外を発生させます。

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
AttributeError: type object 'CalledProcessError' has no attribute 'returncode'

私はどこが間違っているのかわからないことを認めます。

22
michaelmeyer

プロセス出力と返されたコードの両方を取得するには:

from subprocess import Popen, PIPE

p = Popen(["ls", "non existent"], stdout=PIPE)
output = p.communicate()[0]
print(p.returncode)

subprocess.CalledProcessErrorはクラスです。 returncodeにアクセスするには、例外インスタンスを使用します。

from subprocess import CalledProcessError, check_output

try:
    output = check_output(["ls", "non existent"])
    returncode = 0
except CalledProcessError as e:
    output = e.output
    returncode = e.returncode

print(returncode)
38
jfs

ほとんどの場合、私の答えはもはや関係ありませんが、このコードで解決できると思います。

import subprocess
failing_command='ls non_existent_dir'

try:
    subprocess.check_output(failing_command, Shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
    ret =   e.returncode 
    if ret in (1, 2):
        print("the command failed")
    Elif ret in (3, 4, 5):
        print("the command failed very much")
2