" Linux:The Complete Reference 6th Edition "(pg。44)によると、|&
を使用して、onlySTDERRをパイプすることができますリダイレクト記号。
これをテストするためのかなり単純なスクリプトを作成しました。
#!/bin/bash
echo "Normal Text."
echo "Error Text." >&2
このスクリプトは次のように実行します。
./script.sh |& sed 's:^:\t:'
おそらく、STDERRに出力される行だけがインデントされます。しかし、私が見るように、それは実際にはこのように機能しません:
Normal Text.
Error Text.
ここで何が悪いのですか?
あなたの本がどのテキストを使用しているのかはわかりませんが、 bash manual は明確です(すでにリダイレクトに慣れている場合)。
|&
が使用されている場合、コマンド1の標準エラーは、その標準出力に加えて、パイプを介してコマンド2の標準入力に接続されます。2>&1 |
の短縮形です。この標準エラーから標準出力への暗黙的なリダイレクトは、コマンドで指定されたリダイレクトの後に実行されます。
したがって、標準出力と標準エラーを混在させたくない場合は、標準出力を別の場所にリダイレクトする必要があります。参照 標準エラーストリーム(stderr)をgrepする方法?
{ ./script.sh 2>&1 >&3 | sed 's:^:\t:'; } 3>&1
ただし、script.sh
およびsed
のfd 1と3はどちらも、元のstdout宛先を指します。善良な市民になりたい場合は、これらのコマンドに不要なfd 3を閉じることができます。
{ ./script.sh 2>&1 >&3 3>&- | sed 's:^:\t:' 3>&-; } 3>&1
bash
およびksh93
は、>&3 3>&-
を>&3-
に圧縮できます(fd move)。
|&
は、2>&1 |
のようにstderrをstdinにパイプするため、次のプログラムはstdinで両方を取得します。
$cat test.sh
#!/bin/bash
echo "Normal Text."
echo "Error Text." >&2
$./test.sh | sed 's:^:\t:'
Error Text.
Normal Text.
$ ./test.sh |& sed 's:^:\t:'
Normal Text.
Error Text.
bashの|&
は2>&1 |
の(あまり移植性のない)ショートカットにすぎないため、すべての行がインデントされているはずです。