これらは、私のテストファイルです:処理stdoutとstderr:間違った順序
std-test.sh:
#!/bin/bash
for i in {0..20}
do
number=$RANDOM
let "number %= 10"
if [ $number -le 6 ]
then
echo $i;
else
echo $i 1>&2;
fi
done
process.sh:
#!/bin/bash
while read line; do
[[ $1 = "err" ]] && echo "$(date +%s%3N) $line" >> stderr;
[[ $1 = "out" ]] && echo "$(date +%s%3N) $line" >> stdout;
done
std-test.sh
は、その行番号を含む20行を作成し、 process.sh
はパイプされたときに別のコマンド出力を読み取ることができますが、0123に保存します引数としてerr
が渡された場合は、out
が渡された場合はstdout
になります。全体をテストするコマンドは、 ./std-test.sh 2> >(./process.sh err) > >(./process.sh out)
(hereから取得)です。次のように私のテスト出力は、次のとおり
stdout:
1486297129986 0
1486297129987 1
1486297129988 2
1486297129988 3
1486297129989 4
1486297129990 6
1486297129991 7
1486297129991 8
1486297129992 9
1486297129993 10
1486297129993 11
1486297129994 12
1486297129995 14
1486297129995 17
1486297129996 18
stderr:
1486297129986 5
1486297129987 13
1486297129987 15
1486297129988 16
1486297129989 19
1486297129990 20
I出力を解析しようとしたとき、私はstderr
とstdout
の順序は完全に台無しにされていることを、実現しました。 stderr
の5がstdout
の1の前に来るのはなぜですか?または13の直後ですか?私がここで作ったミスは何ですか?どうすれば解決できますか?
編集#1:私は直接ファイルへのパイプの標準エラー出力と標準出力できたけど、process.sh
は、リモートサーバに結果をカールします。ファイルに保存することはPOCのようなものです。
編集#2:私は、プログラムでドッカーログをタイムスタンプして処理しようとしています。
フラッシングの問題だと思います。 stderrとstdoutはエコー後に直接フラッシュされないかもしれません。 stderrは常にバッファがいっぱいになったときにだけフラッシュされますが、stderrは常に即座にフラッシュされるようです。たとえば、https://www.turnkeylinux.org/blog/unix-buffering –