前のコマンドが失敗した場合はパイプを終了します。

前のコマンドが失敗した場合はパイプを終了します。

スクリプト出力を解析して、実行中または待機中のPBSジョブのqstat -tn1数を確認しようとしていますbash。これはこれまでうまくいきました。

count ()
{
    qstat -tn1 | awk '
        BEGIN { R = 0; Q = 0; }
        $10 == "R" { R++ }
        $10 == "Q" { Q++ }
        END { print R, Q }'
}

if read -r R Q < <(count)
    ...

qstatただし、時には不明な理由で失敗することがあります。この場合、何も印刷せずにいくつかのstdoutエラーメッセージを印刷し、stderrゼロ以外の状態(通常は標準)で終了します。ただし、awk失敗して受信した空の入力をqstat幸せに印刷します。0 0その後、read両方に0を割り当て、R実際に失敗したかどうかはQわかりません。qstat

  1. R実行中のプロセスや待機中のプロセスがない可能性があるため、スクリプトブロックでゼロに初期化する必要があります。これらのプロセスの数を取得するには、空の文字列だけを印刷するのではなく印刷する必要があります。QBEGINawk0
  2. これによりゼロ以外の状態で終了できset -o pipefailますが、終了状態は表示されず、とにかく空の入力を実行して印刷します。countreadawk0 0
  3. 名前付きパイプとサブプロセスを試してみることもできますが、管理が複雑すぎると感じます。

count発信者が失敗を検出するための良い方法はありますか?

ベストアンサー1

countプロセス置換を読み取ると、戻り状態が得られないと思います。だからしないでください。代わりに、結果を変数に保存するか、パイプを使用してください。

count=$(count)
if [ $? -eq 0 ]; then
  read -r R Q <<<"$count"

または

set -o pipefail
if count | { read -r R Q; … }

PIPESTATUS別の可能性は、変数を使用して最初のコマンドの戻り状態を確認することです。

count=$(qstat -tn1 | awk …)
if ((${PIPESTATUS[0]} == 0)); then
  read P Q

または、入力が空の場合、awkは一意の項目(何もなし)を印刷する準備をします。

awk '
    BEGIN { R = 0; Q = 0; }
    $10 == "R" { R++ }
    $10 == "Q" { Q++ }
    END { if (NR) print R, Q }'

ifnefromを使用して、コマンドへの入力が空であるかどうかをテストできます。その他のユーティリティまたは他の方法。しかし、awkでパイプを接続しているので、既存のawkスクリプトで実行することをお勧めします。

コマンドから戻り状態を取得する必要がある場合は、追加のqstat入力行としてawkに提供できます。簡単に解析するには、最後の行を一意の形式で並べ替えます。

{
  qstat -tn1
  echo exit_code = $?
} | awk '
    /^exit_code = / { status = $3 }
    END { if (status == 0) print Q, R }
'

おすすめ記事