stdoutをパイピングせずにstderrをパイピングする方法


24

標準出力ストリームをパイプせずに標準エラーストリームをパイプする方法を教えてください。

このコマンドが機能することは知っていますが、標準出力も記述します。

Command 2>&1 | tee -a $LOG

標準エラーを取得するにはどうすればよいですか?

注:これから欲しいのは、stderrストリームをログに書き込み、stderrとstdoutの両方をコンソールに書き込むことです。

回答:


26

これを行うには、1つの追加ファイル記述子を使用して、stderrとstdoutを切り替えます。

find /var/log 3>&1 1>&2 2>&3 | tee foo.file

基本的には、次のように機能します。少なくとも機能すると思います
。リダイレクトは左から右に評価されます。

3>&1 新しいファイル記述子を作成します。3はfd 1(stdout)の複製(コピー)です。

1>&2 stdout(1)をfd 2(stderr)の複製にします

2>&3 fd 2を3の複製(コピー)にします。以前はstdoutのコピーでした。

これで、stderrとstdoutが切り替えられました。

| tee foo.file teeは、stderrにされたファイル記述子1を複製します。


ああ、kshのをテストしていませんは、bashで動作します...しかし
カイルブラント

おかげで、kshでも動作します。ほとんどのパイプとストリームはposix標準だと思います。
C.ロス

「コピー」は実際には正しくありません。@Guasqueñoの回答を参照してください。
カイルブラント

これはWindowsでも機能しますtee.exe:)
Acorn

13

KyleのUnix / Linuxコマンドは、STDERRをSTDOUTに切り替える作業を行います。ただし、説明はまったく正しくありません。リダイレクト演算子はコピーや複製を行わず、フローを別の方向にリダイレクトします。

3>&1を一時的に最後に移動してKyleのコマンドを書き換えると、概念を理解しやすくなります。

find /var/log  1>&2  2>&3  3>&1  

このように書かれた場合、&3は3>&1の前にあるため、&3はまだ存在しないため、Linuxはエラーを表示します。3>何かは、3番目のパイプを使用することを宣言(定義)する方法です。そのため、たとえば、Kyleが書いたように、そのパイプに水を流す前に配置する必要があります。楽しみのためにこの他の方法を試してください:

((echo "STD1";  anyerror "bbbb"; echo "STD2" ) 3>&1 4>&2 1>&4 2>&3) > newSTDOUT 2> newSTDERR

コピーを行う方法がないことは残念です。Linuxは同じコマンドで「3>&1 3>&2」のようなことはできません。Linuxは最初に見つかったもののみを使用し、2番目のものを無視するからです。

エラーと通常の出力の両方をファイルに送信し、1つのコマンドでエラーのコピーを標準出力に送信する方法を(まだ)見つけていません。インスタンスの場合、両方の出力(エラーと標準)をログファイルに出力し、エラーを出してblackBerryに電子メールメッセージを送信するcronジョブがあります。「tee」を使用して2つのコマンドで実行できますが、エラーはファイルの通常の出力行の中で正しい順序で表示されません。これは私が問題を解決したい方法です:

((echo "STD1"; sdfr "bbbb"; echo "STD2" ) 3>&1 1>&2 2>&3 | tee -a log1 ) 2>> log1

log1を2回使用する必要があり、両方のケースで追加する必要があることに注意してください。1つ目は「tee」コマンドに「-a」オプションを使用し、2つ目は「>>」を使用します。

こう猫LOG1ますが、以下のものを:

STD1
STD2
-bash: sdfr: command not found

エラーは2行目には表示されないことに注意してください。


素晴らしい補正!
カイルブラント

FDを複数回リダイレクトできるようにするには、zshとmult_iosオプション(デフォルトでオン)を確認してください。
トム・ヘイル

2

ksh(pdksh)のmanページによると、次のことができます:

コマンド2>&1> / dev / null | 猫-n

すなわち、dup stderrをstdoutに、stdoutを/ dev / nullにリダイレクトしてから、「cat -n」にパイプします。

私のシステムのpdkshで動作します:

$ errorecho(){echo "$ @">&2;}

$ errorecho foo
foo

$ errorecho foo> / dev / null#リダイレクトされたstdoutでも表示されます
foo

$ errorecho foo 2>&1> / dev / null | 猫-n
     1 foo
$   

BusyBoxでも動作します
ウドG

1

私もそれを必要とし、あなたのコマンドを洗練したので、私はあなたが望むようにそれを実行しました。今私にとっては、これを使用してdebian squeezeでbash 3.2を使用して正しく動作します

(echo "foo" 3>&1 1>&2 2>&3 | tee -a log1 ) 2>> log1 >> log2

一方、log1はstdoutとstderrを記録し、log2はstderrのみを記録し、画面に出力するものは何もありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.