web-dev-qa-db-ja.com

bashを使用して、標準エラーを別のプロセスにパイプするにはどうすればよいですか?

プロセスの標準出力を別のプロセスの標準入力にパイプする方法はよく知られています。

proc1 | proc2

しかし、proc1の標準エラーをproc2に送信し、標準出力を現在の場所に残したい場合はどうなりますか? bashには次の行に沿ったコマンドがあると思うでしょう。

proc1 2| proc2

しかし、悲しいかな、いや。これを行う方法はありますか?

120
paxdiablo

プロセス置換 もあります。プロセスがファイルの代わりになります。
次のようにstderrをファイルに送信できます。

process1 2> file

ただし、次のようにファイルのプロセスを置き換えることができます。

process1 2> >(process2)

stderrを画面に送信し、ログファイルに追加する具体的な例を次に示します

sh myscript 2> >(tee -a errlog)
148
Scot

次のトリックを使用してswapstdoutおよびstderrにできます。次に、通常のパイプ機能を使用します。

( proc1 3>&1 1>&2- 2>&3- ) | proc2

stdoutstderrの両方が開始時に同じ場所を指している場合、これは必要なものを提供します。

x>yビットが行うことは、ファイルハンドルxが現在のファイルハンドルyが指す場所に情報を送信するように変更することです。特定の場合:

  • 3>&1new handle 3を作成します。これはcurrent handle 1(元のstdout)に出力され、以下の最後の箇条書きのどこかに保存します。
  • 1>&2は、ハンドル1(stdout)を変更してcurrentハンドル2(元のstderr)に出力します。
  • 2>&3-は、ハンドル2(stderr)を変更してcurrentハンドル3(元のstdout)に出力し、ハンドル3を閉じます(末尾の-を介して)。

ソートアルゴリズムで実際に表示されるスワップコマンドです。

temp   = value1;
value1 = value2;
value2 = temp;
87
paxdiablo

Bash 4には次の機能があります。

`|& 'を使用すると、command1の標準エラーがパイプを介してcommand2の標準入力に接続されます。 2>&1 |の省略形です。この標準エラーの暗黙的なリダイレクトは、コマンドで指定されたリダイレクトの後に実行されます。

zshにもこの機能があります。

-

他の/古いシェルでは、これを明示的に入力するだけです

FirstCommand 2>&1 |その他のコマンド

64

スワップは問題を解決するので素晴らしいです。元の標準出力さえ必要ない場合に備えて、次の方法でそれを行うことができます。

proc1 2>&1 1>/dev/null | proc2

順序は重要です。あなたはしたくないでしょう:

proc1 >/dev/null 2>&1 | proc1

これにより、すべてが/dev/nullにリダイレクトされます!

26
kccqzy

これらのどれも実際には非常にうまくいきませんでした。私が見つけた最良の方法は、あなたが望むことをすることです:

(command < input > output) 2>&1 | less

これは、commandがキーボード入力を必要としない場合にのみ機能します。例えば:

(gzip -d < file.gz > file) 2>&1 | less

gzipエラーをlessに入れます

0
sbingner