web-dev-qa-db-ja.com

サブプロセスコマンドのエラーメッセージを保存する

サブプロセスを使用してbashコマンドを実行すると、コマンドが無効になる場合があります。この場合、bashはエラーメッセージを返します。このメッセージをどのようにキャッチできますか?このメッセージをログファイルに保存したいと思います。以下は、存在しないディレクトリにあるファイルを一覧表示しようとする例です。

try:
    subprocess.check_call(["ls", "/home/non"]) 
    df = subprocess.Popen(["ls", "/home/non"], stdout=subprocess.PIPE)        
    output, err = df.communicate()
    # process outputs
except Exception as error:        
    print error
    sys.exit(1)

Bashは「ls:/ home/nonにアクセスできません:そのようなファイルまたはディレクトリはありません」と出力します。このエラーメッセージを取得するにはどうすればよいですか?例外行でキャッチされたエラーは明らかに異なり、「コマンド '[' ls '、'/home/non ']'がゼロ以外の終了ステータス2を返しました」と表示されます。

11
Luke

Stderrをファイルオブジェクトにリダイレクトできます。

from subprocess import PIPE, CalledProcessError, check_call, Popen

with open("log.txt", "w") as f:
    try:
        check_call(["ls", "/home/non"], stderr=f)
        df = Popen(["ls", "/home/non"], stdout=PIPE)
        output, err = df.communicate()
    except CalledProcessError as e:
        print(e)
        exit(1)

Log.txtへの出力:

ls: cannot access /home/non: No such file or directory

以下以外のメッセージが必要な場合:

try:
    check_call(["ls", "/home/non"])
    df = Popen(["ls", "/home/non"], stdout=PIPE)
    output, err = df.communicate()
except CalledProcessError as e:
    print(e.message)

python 2.6の場合、e.messageは機能しません。python 2.7のcheck_outputの同様のバージョンを使用できます。 python 2.6:

from subprocess import PIPE, CalledProcessError, Popen

def check_output(*args, **kwargs):
    process = Popen(stdout=PIPE, *args, **kwargs)
    out, err = process.communicate()
    ret = process.poll()
    if ret:
        cmd = kwargs.get("args")
        if cmd is None:
            cmd = args[0]
        error = CalledProcessError(ret, cmd)
        error.out = out
        error.message = err
        raise error
    return out

try:
    out = check_output(["ls", "/home"], stderr=PIPE)
    df = Popen(["ls", "/home/non"], stdout=PIPE)
    output, err = df.communicate()
except CalledProcessError as e:
    print(e.message)
else:
    print(out)
6

"ls:/ home/nonにアクセスできません:そのようなファイルまたはディレクトリはありません"lsコマンドによって生成されますnotbashここ。

例外処理を使用して存在しないファイルを処理する場合は、subprocess.check_output()を使用します。

#!/usr/bin/env python
from subprocess import check_output, STDOUT, CalledProcessError

try:
    output = check_output(['ls', 'nonexistent'], stderr=STDOUT)
except CalledProcessError as exc:
    print(exc.output)
else:
    assert 0

出力

ls: cannot access nonexistent: No such file or directory
9
jfs