web-dev-qa-db-ja.com

CalledProcessErrorからの出力を確認します

Pingコマンドを実行するために、pythonsサブプロセスモジュールのsubprocess.check_outputを使用しています。ここに私がそれをやっている方法があります:

output = subprocess.check_output(["ping","-c 2 -W 2","1.1.1.1")

CalledProcessErrorを発生させ、出力が関数の引数の1つであると言います。誰もがその出力の読み方を手伝ってくれますか?出力を文字列に読み取り、解析したいと思います。たとえば、pingが返される場合

100%のパケット損失

それをキャプチャする必要があります。他のより良い方法がある場合..提案してください。ありがとう。

39
ash

引数のリストでは、各エントリは独立している必要があります。を使用して

output = subprocess.check_output(["ping", "-c","2", "-W","2", "1.1.1.1"])

あなたの問題を修正する必要があります。

13
phihag

Python osモジュールのドキュメント os.popenによると、Python 2.6。

現代のPythonの解決策は、サブプロセスモジュールのcheck_output()を使用することだと思います。

サブプロセスPython documentation から:

subprocess.check_output(args、*、stdin = None、stderr = None、Shell = False、universal_newlines = False)引数付きでコマンドを実行し、その出力をバイト文字列として返します。

戻りコードがゼロ以外の場合、CalledProcessErrorが発生します。 CalledProcessErrorオブジェクトの戻りコードはreturncode属性に、出力はoutput属性に含まれます。

Python 2.7(以降)で次のコードを実行した場合:

import subprocess

try:
    print subprocess.check_output(["ping", "-n", "2", "-w", "2", "1.1.1.1"])
except subprocess.CalledProcessError, e:
    print "Ping stdout output:\n", e.output

次のような出力が表示されるはずです。

Ping stdout output:

Pinging 1.1.1.1 with 32 bytes of data:
Request timed out.
Request timed out.

Ping statistics for 1.1.1.1:
Packets: Sent = 2, Received = 0, Lost = 2 (100% loss),

E.output文字列は、OPのニーズに合わせて解析できます。

リターンコードまたはその他の属性が必要な場合、それらはCalledProccessErrorにあります。これは、pdbをステップスルーすることで確認できます。

(Pdb)!dir(e)   

['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
 '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__',
 '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
 '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 
 '__unicode__', '__weakref__', 'args', 'cmd', 'message', 'output', 'returncode']
150
krd

Stdoutとstderrを取り戻したい場合(発生した場合のCalledProcessErrorからの抽出を含む)、次を使用します。

command = ["ls", "-l"]
try:
    output = check_output(command, stderr=STDOUT).decode()
    success = True 
except CalledProcessError as e:
    output = e.output.decode()
    success = False

これはPython 2および3互換です。

コマンドが配列ではなく文字列の場合、これに次の接頭辞を付けます。

import shlex
command = shlex.split(command)
3
Zags

@krdに感謝します。エラーキャッチプロセスを使用していますが、printステートメントとexceptステートメントを更新する必要がありました。 Linux Mint 17.2でPython 2.7.6を使用しています。

また、出力文字列がどこから来たかは不明でした。私の更新:

import subprocess

# Output returned in error handler
try:
    print("Ping stdout output on success:\n" + 
           subprocess.check_output(["ping", "-c", "2", "-w", "2", "1.1.1.1"]))
except subprocess.CalledProcessError as e:
    print("Ping stdout output on error:\n" + e.output)

# Output returned normally
try:
    print("Ping stdout output on success:\n" + 
           subprocess.check_output(["ping", "-c", "2", "-w", "2", "8.8.8.8"]))
except subprocess.CalledProcessError as e:
    print("Ping stdout output on error:\n" + e.output)

次のような出力が表示されます。

Ping stdout output on error:
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.

--- 1.1.1.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1007ms


Ping stdout output on success:
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=59 time=37.8 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=59 time=38.8 ms

--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 37.840/38.321/38.802/0.481 ms
0
AndruWitta

私は同じ問題に遭遇し、 documentation にこのタイプのシナリオの例があることがわかりました(STDERR TO STDOUTを記述し、常に戻りコード0で正常に終了します)例外を発生/キャッチしません。

output = subprocess.check_output("ping -c 2 -W 2 1.1.1.1; exit 0", stderr=subprocess.STDOUT, Shell=True)

これで、標準の文字列関数findを使用して、出力文字列outputを確認できます。

0
Joseph