内容へ移動
とあるエンジニアの闇歴史帳
コピペで使える便利Wiki ※現在構築中です。
ユーザ用ツール
ログイン
トレース:
perl:file_readgrowfile
この文書は読取専用です。文書のソースを閲覧することは可能ですが、変更はできません。もし変更したい場合は管理者に連絡してください。
====== 成長するファイルを読み込み続ける - Perl ====== ~~socialite~~ <note important>この記事は2007年05月18日に書かれた物です</note> 例えばApacheのアクセスログやエラーログなどは、アクセスがある限り半永久的にデータがファイルに追記(記録)されていく。このような成長し続けるファイルを常に読み込み、表示し続けるにはどうすれば良いだろうか? 原理は簡単だ。 '' while(<FILE>){print ;} '' のようなプログラムの場合、ファイルの終端を表すEOF(End Of File)が来たタイミングでPerlの内部にフラグが立ち、それ以上ファイルポインタが先に進まなくなってしまう。 ところが一旦EOFが来たら、seek関数を実行するだけでこのフラグが消えるという性質がある。これを利用するのだ。 ===== サンプル ===== <code perl> #!/usr/bin/perl ;# ;#成長するファイルを追いかける ;# #------------------------------------------------# #ライブラリ #------------------------------------------------# use strict; #------------------------------------------------# #メインルーチン #------------------------------------------------# package main;{ my $file = $ARGV[0] || usage(); my $sec = $ARGV[1] || 3; my $position = 0; #----------------------------# # エラーチェック # #----------------------------# die "Not FILE PATH" if( $file !~ /^([a-zA-Z0-9¥.¥_¥/¥-]{1,})$/ ); die "Not found ($file)" if( not -f $file ); die "Can not READ ($file)" if( not -r $file ); die "Not INTEGER ($sec)" if( $sec and $sec !~ /^([0-9]{1,})$/ ); #----------------------------# # 追跡開始 # #----------------------------# open(DAT, $file) or die("Can not open ($file) $!"); for(;;){ seek(DAT, $position, 0); #seekするとEOFフラグも解除される while(<DAT>){ #現在の末尾(EOF)まで処理する #-- 表示 --# print ; #-- 復帰用に現在位置を取得 --# $position = tell(DAT); } sleep( $sec ); } close(DAT); #実行されない。気持ち悪いならシグナル処理を入れる exit; } #------------------------------------------------# #[function]使用説明、終了 #------------------------------------------------# sub usage { print <<'END_OF_TXT'; 使用方法: endless "file" [second] --- 成長するファイルを Ctrl + C などで終了されるまで表示し続ける。 (ログファイルなどをエンドレスにcatする。end-less) --- file ..... ファイルのパス。必須。 second ... ファイルの成長が早い場合は少なく(1〜2) そうでない場合は大きな値を設定する(5〜) 未指定の場合は3。 END_OF_TXT exit; } </code> まず無限ループ中でファイルを最初から最後まで全て処理する。その後ファイルを閉じないでsleep。EOFフラグ解除のためfseek。ループの最初にもどりまたファイルを表示する処理を行うことで実現できる。ちょっとしたデーモンのように動作する。 ※Ctrl+Cなどで終了させること。 用途としては例えばエラーログを常に表示する、ファイルにデータが追記された瞬間に何らかの処理を走らせるトリガーとして使用できる。指定した時間にプログラムを実行してくれるcronでは間に合わない要件を満たさないなどの状況に出くわしたらこういった手段も検討すると良いかもしれない。 ※個人的にはデバグ程度にとどめるのをオススメするが。 余談だが、[[http://www.amazon.co.jp/exec/obidos/ASIN/4873112028/ichikorocom-22/ref=nosim/|Perlクックブック]]にあった以下のコードがこちらの環境(Debian3.2 + Perl5.8)で動作しなかった。 <code perl> exit if( (stat(FILE))[3] ==3 ) </code> ファイルが削除された、または読み込めなくなった際の処理が必要なのだが、ファイルテスト演算子などもうまく動作しないようだ。これらが分かる方はアドバイスなど求む。 ===== 関連書籍 ===== {{amazon>jp:4873113008}} <html><p style="clear:both"></p></html> {{amazon>jp:B00ISP0OM8}} <html><p style="clear:both"></p></html> {{tag>CGI・Perl例文集 Perl ファイル }} ~~socialite~~
関連ページ
perl/file_readgrowfile.txt
· 最終更新: 2020/06/23 14:10 (外部編集)
ページ用ツール
文書の表示
バックリンク
文書の先頭へ