によると」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 |
ので、すべての行をインデントする必要があります。