データをパイプしてデータの「到着」を表示する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として印刷します。