データをスクリプトまたは関数にパイピングするときに、出力がstdoutに行くかstderrに行くかを決定します。

データをスクリプトまたは関数にパイピングするときに、出力がstdoutに行くかstderrに行くかを決定します。

データをパイプしてデータの「到着」を表示するfd(stdoutまたはstderr)を出力の前に追加できる一般的な関数またはスクリプトを作成しようとしています。私のBash技術はせいぜい平均レベルであり、{ foo 2>&1 >&3 3>&- | bar 3>&-; } 3>&1

これが可能かどうか、そしてそれを達成する方法を提案できる人はいますか?

本質的に私は次のことをしたいと思います。

$ { echo "foo" ; echo "bar" 1>&2 ; } | my_output_processor.sh
stdout: foo
stderr: bar 

私は読んだパイプSTDERRとSTDOUTしかし、それは私に答えられませんでした。私の考えに答えるhttps://unix.stackexchange.com/a/440439/307184手がかりが含まれている可能性がありますが、データパイプラインではなく実行スクリプトでのみ機能するようです。

私のmacOSのBashバージョンは5.0です。

編集する:@Glenn以下の答えがうまくいきます!私はタイピングを節約し、エラーを防ぐためにいくつかの小さなヘルパー関数を作成し、次のようにテストしました。

$ out(){ sed "s/^/out: /" ;} ; err(){ sed "s/^/err: /" 1>&2 ;}
$ { echo "good" ; echo "bad" >&2; } 2> >(err) 1> >(out)
err: bad
out: good

リダイレクト順序に関する次の質問:2> >(err) 1> >(out)うまくいき、うまく1> >(out) 2> >(err)いかないのはなぜですか? (修正する:以下の@RudiCの答え - ヘルパー機能が更新され、今度は任意の順序で動作します。

ベストアンサー1

使用プロセスの交換パイプではない:

{ echo "foo" ; echo "bar" >&2; } 2> >(sed "s/^/err: /") > >(sed "s/^/out: /")
err: bar
out: foo

スクリプトでこれを行う場合は、次のexecコマンドを使用してスクリプト全体の期間にリダイレクトを設定します。

bash -c '
    exec 2> >(sed "s/^/err: /") > >(sed "s/^/out: /")
    echo foo
    echo bar >&2
'
err: bar
out: foo

そうすれば

exec > >(sed "s/^/out: /") 2> >(sed "s/^/err: /")

その後、出力は次のようになります。

out: foo
out: err: bar

私はこれが「動作しない」という意味だと思います。これは、デフォルトでは、標準出力に移動する「err」プロセス置換の出力が「out」プロセスサブプロセスに渡されるためです。問題を解決するには、次の手順を実行する必要があります。

exec 3>&1 > >(sed "s/^/out: /") 2> >(sed "s/^/err: /" >&3)

デフォルトのstdoutを指す別のファイル記述子(3)を作成し、stderrをリダイレクトしてfd3として印刷します。

おすすめ記事