standard error
...についての私のstandard output
知識は非常に限られています。
一般的な方法の1つはstandard error
にリダイレクトすることです。これは、リダイレクトのためにstandard output
エラー(通常発生するエラー)が再現されないことを意味しますか?standard error
standard error
standard error
これが真であれば、コピーしてコピーをリダイレクトし、元のコンテンツをstandard output
期待どおりにリダイレクトする方法はありますか?standard error
答え1
私がUnixを初めて使用したとき、誰かがパイプがパイプのように動作することを説明しました。
プロセスには基本的に塗りつぶすための3つの接続点があります。
stdin
|
+--+--+
| pgm |
++---++
| |
stdout stderr
したがって、これを行うと、次のようなcat | grep pattern
結果が得られます。
stdin
|
+--+--+
| cat |
++---++
stdout| |stderr
| \
stdin| \
+------+ |
| grep | |
+-+---++ |
stdout| | |
| \__ |
| \|
| |stderr
(当時は全てアスキーグラフィックだったのに…)
示されているようにstderrをstdoutにリダイレクトすると、pgm 2>&1
図は次のようになります。
stdin |
|
+--+--+
| pgm |
++---++
stdout| |stderr
| /
| /
| /
|/
|
理論的には、この方法で多くの配管作業を実行できます。たとえば、awk '{print;print > "/dev/stderr"}'
stdinをstdoutとstderrにコピーします。
しかし、非常に急速に混乱する可能性があります。詳細については、bashのマニュアルを参照してください。
メモ:pgm = 上図のプログラムです。
編集:楽しく、単純なシェルスクリプトを使ってもう少し複雑な配管を試してみました。
generate.sh
:
echoerr() { echo "$@" 1>&2; }
for i in 1 2 3 4 5 6 ; do
echo "STDOUT $i"
echoerr "STDERR $i"
done
そしてcopytee.sh
:
#!/bin/bash
echoerr() { echo "$@" 1>&2; }
while read line; do
echo "stdout $line"
echoerr "stderr $line"
done
(コピー広告は小文字、生成は大文字です)
高度な形式のリダイレクトを取得するには、bash generate.sh 2> >(bash copytee.sh )
次のように出力します。
STDOUT 1
STDOUT 2
STDOUT 3
STDOUT 4
STDOUT 5
STDOUT 6
stdout STDERR 1
stderr STDERR 1
stdout STDERR 2
stderr STDERR 2
stdout STDERR 3
stderr STDERR 3
stdout STDERR 4
stderr STDERR 4
stdout STDERR 5
stderr STDERR 5
stdout STDERR 6
stderr STDERR 6
これがまさにあなたが要求したものです。
答え2
「標準エラー」は特に定義された場所ではありません。 「標準エラー」は、ファイル記述子 2 に追加されるすべてです。
「標準エラー」を「標準出力」にリダイレクトする場合は、ファイルディスクリプタ2を閉じてからファイルディスクリプタ1のコピーで再度開くと、そのファイルディスクリプタ1にその瞬間のすべての場所に正確に添付されます。元のファイル記述子2が失われます(文字通りファイル記述子が閉じられます)。したがって、あなたが望むものを正確にすることはできません。 「標準エラー」を別の場所にリダイレクトすると、ファイルディスクリプタ2が閉じて(そしてリダイレクトされた場所に添付するために再び開きます)、位置情報が「あるべき」場所に関する情報はもうありません。