私はPerlを使用して、任意の時点で切り捨てられる可能性のあるログファイルを読み取ります。これが発生した場合、最初からファイルの読み取りを再開したいのですが、デフォルトのPerlの動作は、ファイルポインターが追いつくまで待機するようです。たとえば、次のコマンドを実行すると、次のようになります。
perl -e 'open FILE, "test"; while (1) { $line = <FILE>; print "$line"; }'
そして、次のことを行います。
for i in 1 2 3; do echo $i >> test; done
:>test
for i in 4 5 6 7; do echo $i >> test; done
私が得る出力は次のとおりです。
1
2
3
7
しかし、同じことをする場合は、Perlコードを次のように置き換えます。
tail -f test
次に(stderrへのテール出力を無視して)必要な出力を取得します。つまり、次のようになります。
1
2
3
4
5
6
7
もちろん、ライン自体に何らかの処理を加えたいので、テールだけを使用することはできません。私が持っていた1つの考えは、2つを組み合わせることでした。
tail -f test | perl -e 'while (1) { $line = <STDIN>; print "$line"; }'
これは私のLinux開発マシンでは動作しますが、残念ながらSolarisターゲットプラットフォームでは動作しません。
何か案は?
要求に応じて、File::Tailの使用例は次のとおりです。
perl -e 'use File::Tail; $file = File::Tail->new("test"); while (defined($line=$file->read)) { print "$line"; }'
次に、前と同じようにデータをテストに入力すると、得られる出力は次のようになります。
7
これは明らかに望まれることではありません。File::Tailが次のように待機するmaxintervalを調整しようとしました。
perl -e 'use File::Tail; $file = File::Tail->new(name => "test", maxinterval => 1); while (defined($line=$file->read)) { print "$line"; }'
ただし、その場合は、次のように、テストファイルへのデータの入力が速すぎます。
for i in 1 2 3; do echo $i >> test; done; :>test; for i in 4 5 6 7; do echo $i >> test; done
結果は次のようになります。
4
5
6
7
残念ながら、これは私たちの(非常に忙しい)アプリケーションにとって現実的なシナリオです。比較のために、Linuxテールはその種のデータ入力速度を適切に処理しているように見えるので、それができることはかなり明らかです(公平ではありますが、Perlではないかもしれません...?)