3

複数のパイプステップを含む、Python から UNIX システムで実行されるコマンドをコンパイルしています。例えば:

grep foo myfile | cmd1 | cmd2 > output

fooこれらは、 fromを持つエントリの一連の変換に対応しますmyfile。モジュールによって実行されるコマンドとして構築することもあれば、モジュールos.systemを使用して構築することもあります。subprocess

Python から、パイプの各部分でエラー チェックを行うにはどうすればよいですか? たとえば、99% のケースでfooエントリがmyfileあり、残りのパイプは機能します。ただし、何らかの理由でmyfile存在するがfooエントリが含まれていない場合は、空のファイルをパイプしているため残りのパイプが壊れ、残りのコマンドが機能するには空でない入力が必要です。これにより、壊れたパイプの出力しか表示されず、どの中間ステップが失敗したかがわからないため、デバッグが困難になります。

Python で中間ステップをエラーチェックするパイプを構築する方法はありますか? たとえばgrep、パイプの部分に実際に何らかの出力が含まれていること、の入力のcmd1出力にgrepも何らかの出力が含まれていることなどを確認しますか? ありがとう。

4

3 に答える 3

0

これは私のアプローチです。すべての状態コードの合計であり、「echo 1 |echo 2」または「cat test |echo 2」という結果で終了し、コマンドに置き換えます

>>getstatusoutput('status=0;echo 1 |echo 2;for ((i=0;i<${#PIPESTATUS[*]};i++));do let status=${status}+${PIPESTATUS[ ${i}]};done;exit $status')

(0, '2')

>> getstatusoutput('status=0;cat test |echo 2;for ((i=0;i<${#PIPESTATUS[*]};i++));do let status=${status}+${PIPESTATUS[ ${i}]};done;exit $status')

(1, '2\ncat: テスト: そのようなファイルまたはディレクトリはありません')

于 2020-11-20T06:35:38.287 に答える
0

基本的には Mingjiang Shi's answer と同じです。これには、必要なすべての重要な情報がほとんど含まれていますが、追加の機能がなく、問題が修正されています。(そして python 2.7.12 と 3.5.2 でテスト済み)

$PIPESTATUS は sh には存在しないため、ディストリビューションに(を使用する Ubuntu など) のよう/bin/shに動作するがない場合は、実行可能ファイルを bash に設定する必要があります。これは配列なので、配列のように使用することを好みます。bashdash

そして、wait()の代わりにをお勧めcommunicate()します。そうすれば、スラープの代わりにフィルターをかけることができます (処理する前に出力全体をメモリにロードする代わりに、小さなバッファーに読み込むときに使用します)。

したがって、必要なことは次のとおりです。

  • 引数にはリストではなく文字列を使用する必要があります
  • shell=True を使用
  • executable="/bin/bash" を使用

コード:

p = subprocess.Popen("false | true; exit ${PIPESTATUS[0]}", shell=True, executable='/bin/bash', stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# at this point you do your filtering, eg. using p.stdout.readinto(buf)

p.wait()
if p.returncode != 0:
    # handle it here
于 2016-11-26T20:06:12.510 に答える