リダイレクトされていないパイプから stderr を受信する Bash

リダイレクトされていないパイプから stderr を受信する Bash

最初にリダイレクトせずに呼び出すと、内部でstderrを受信/リダイレクトできますかfoo.shbar.shfoo.sh | bar.sh

foo.sh

#!/bin/bash
echo "hello world" >&2

bar.sh

#!/bin/bash
sed -Eu 's/world/everyone/g'
user@pc$ ./foo.sh | ./bar.sh
hello world

user@pc$ ./foo.sh 2>&1 | ./bar.sh
hello everyone

bar.shユーザーが最初の例のように誤って呼び出されても、2番目の例と同じ動作をすることはできますか?

ところでfoo.sh何でも書くことができますstderr。私はただそれを受け取る方法に興味があるだけですbar.sh

答え1

アイデアはstderrのデータをフィルタリングすることなので、ストリームをマージしたり、すべてのstderrを失うことなくこれを行うより良い方法があります。my_command 2> >(grep --invert-match secret_regex >&2)

構文の説明:

  • 2>「コマンドの次の単語に標準エラーを送信する」と言います。
  • >(some_command)標準に送る前に物を送るように言います入力する命令した。
  • >&2grep最後に出力を送信します(ラインいいえマッチシークレット)標準エラーに戻ります。

フィルタリング後に stdout と stderr がそのまま維持される方法を示す例:

$ (echo output; echo error >&2; echo secret >&2) 2> >(grep --invert-match secret >&2)
output
error
$ ((echo output; echo error >&2; echo secret >&2) 2> >(grep --invert-match secret >&2)) 2>/dev/null
output
$ ((echo output; echo error >&2; echo secret >&2) 2> >(grep --invert-match secret >&2)) >/dev/null
error

元の答え:呼び出し時にシェルが設定されるたびに(つまり、2つのコマンドが実行される前に)./foo.sh | ./bar.sh標準エラーが表示されます。標準エラーが指す場所を「ハイジャック」foo.shすることは(ルートアクセスなしで)不可能だと思いますbar.sh。これは大きなセキュリティホールになる可能性があるためです。悪意のあるプロセスは、機密情報を印刷する特定のコマンドの出力をハイジャックする可能性があります。

答え2

bash速記を提供して下さい:

もし|&使用されると、コマンドの標準エラーは、標準出力に加えて command2 の標準入力にパイプされます。2>&1 |

関連情報