stderrをファイルにリダイレクトしますが、stderrが発生した場合にのみ生成しますか? [コピー]

stderrをファイルにリダイレクトしますが、stderrが発生した場合にのみ生成しますか? [コピー]

次のコマンドを実行しています。

parallel --spreadstdin --line-buffered 'some_command 2> `mktemp --tmpdir /tmp/stderr`' | do_something

秘密は、parallel多くのプロセスを作成してすべてのstderrファイルを取得することです。ほとんどは空だから面白くない。標準エラー出力が実際に発生した場合にのみ、シェルにstderrファイルを生成させるにはどうすればよいですか?

答え1

私が知る限り、これは不可能です。シェルは右から左に読み込まれるため、ファイルが存在する場合は2> error作成されます。error私はこの問題を解決する方法がないと思います。

名前付きパイプを使用してその出力をテストするなど、いくつかの複雑なトリックを実行できますが、実際にはそれほど価値がないと思います。代わりに、inotify他の回答の指示に従うか、tmpファイルを作成して別の場所にコピーします(データが含まれている場合)。

tmp=$(mktemp); command 2> "$tmp"; [ -s "$tmp" ] && cp "$tmp" /path/to/log/files

答え2

パラレル --spreadstdin --line-buffered 'some_command 2\

mktemp --tmpdir /tmp/stderr'| do_something && if [test -s /tmp/stderr] then;

  • ファイルが存在し、サイズが0より大きいかどうかをテストする単一行(TRUE)、FALSEの場合は空です。

ITは効果的な仕事をすることです。ビットとバイトの計算を中止し、起動時にinotifywaitトリガーを生成してログが空であることを確認し、結果をデータテーブルに書き込み、完了時にログを消去し、エラーログにキーワードが表示されたときにWebインターフェイスを作成します。 、インターフェースからメールをお送りします。

while:
  do
    inotifywait -e create /tmp/* && \
      if [ -s /tmp/stderr ]
        then
        ##put it in a datatable
        ##remove the log
      fi
  done

iNotifyWaitはカーネルF / Sサブシステムを監視して、ファイルが変更されたことを確認できます(追加が進行中の場合)。それ以外の場合は、ソースコードを修正し、try()catch()またはエラー報告セクション(エラーコードを画面に印刷するセクション)を修正して、エラーを防ぐために再コンパイルします。

答え3

意外と答えが近すぎるSOに関するもう一つの質問この質問に答えようとしましたが、ポイントを逃しました。次のようにシェル関数を定義します(またはスクリプトを作成します)。

save_err()
{
    # Check that "$1" is set and either complain/abort or generate a default.
    if read -r x
    then
        { printf "%s\n" "$x"; cat; } > "$1"
    fi
}

その後、次のように使用されます。

some_command 2> >( save_err $(mktemp --tmpdir /tmp/stderr) )

注:stderr出力が1行の場合は失敗します。 改行文字で終わりません。。この問題を解決するには、関数の内部を次のように変更します。

    if read -r x
    then
        { printf "%s\n" "$x"; cat; } > "$1"
    elif [ "$x" != "" ]
    then
        printf "%s" "$x" > "$1"
    fi

printf代わりにechoダッシュで始めるか、バックスラッシュを含むテキストを防ぐために使用します。 stderr出力の最初の行にASCII以外の文字が含まれていると、問題が発生する可能性があります。

関連情報