パイプSTDERRとSTDOUT

パイプSTDERRとSTDOUT

によると」Linux:完全なリファレンス6版「(44ページ)、パイプできます。ただSTDERR は|&リダイレクト記号を使用します。

私はこれをテストするために非常に単純なスクリプトを書いた。

#!/bin/bash
echo "Normal Text."
echo "Error Text." >&2

このスクリプトを次のように実行します。

./script.sh |& sed 's:^:\t:'

おそらくSTDERRで印刷された行だけをインデントします。しかし、私が見ると、実際には次のように動作しません。

    Normal Text.
    Error Text. 

私がここで何を間違っているのか?

答え1

本にどのテキストを使用したかはわかりませんが、バッシュマニュアル非常に明確です(リダイレクトにすでにある程度慣れている場合)。

使用されると、|&command1の標準エラーは標準出力に加えてcommand2の標準入力にパイプされます2>&1 |。標準エラーを標準出力に暗黙的にリダイレクトすることは、コマンドで指定されたリダイレクトの後に実行されます。

したがって、標準出力と標準エラーを混在させたくない場合は、標準出力を別の場所にリダイレクトする必要があります。バラより標準エラーストリーム(stderr)をどのようにgrepしますか?

{ ./script.sh 2>&1 >&3 | sed 's:^:\t:'; } 3>&1

script.shただし、fds 1と3はsedどちらも元のstdoutターゲットを指します。素晴らしい市民になりたい場合は、そのコマンドで不要なfd 3をオフにできます。

{ ./script.sh 2>&1 >&3 3>&- | sed 's:^:\t:' 3>&-; } 3>&1

bashそして(fd move)にksh93圧縮することができます。>&3 3>&->&3-

答え2

|&たとえば、stderrをstdinにパイプすると、次の2>&1 |プログラムが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.

答え3

|&Bashでは単に(移植性が劣る)ショートカットな2>&1 |ので、すべての行をインデントする必要があります。

関連情報