ホームページ  >  記事  >  バックエンド開発  >  PHP は Linux コマンドテールを実装します

PHP は Linux コマンドテールを実装します

WBOY
WBOYオリジナル
2016-07-23 08:54:591047ブラウズ
PHP は Linux コマンド tail -f を実装します

今日は、以前に誰かが私に尋ねた質問を突然思い出しました。PHP を介して Linux でコマンド tail -f を実装する方法です。ここでは、それを分析して実装します。

考えてみると、これは非常に単純です。ファイルのサイズが変更されたかどうかを確認するために、ファイルの変更された部分が出力されます。ここには詳細な分析がたくさんあります。

初期ファイルが大きすぎる場合、または変更が多すぎる場合

この時、一度に大量のコンテンツを出力すると見づらくなる可能性があるので、ここではしきい値を8192に設定しています。コンテンツの長さがこのしきい値を超えると、最後の8192バイトのみが出力されるため、広範囲のリフレッシュが行われないため、はっきりと見えないという問題があります。

ファイルサイズの変化を検出する方法

この問題はこのプログラムの核心であり、成功できるかどうかはこの部分にかかっています。ここでの私の実装は次のとおりです:

ファイル ハンドル $fp を開きます。ここでのファイル ハンドルはプロセス全体で 1 回だけオープンおよびクローズする必要があるため、ループの外に配置する必要があることに注意してください。 現在のファイル サイズ file_size と file_size_new を両方とも 0 に初期化します。 file_size_new ファイル サイズはループ内で更新されます。PHP でファイル サイズを取得する前に、clearstatcache() 関数を実行してファイル ステータス キャッシュをクリアする必要があることに注意してください。そうしないと、ファイル サイズの取得に誤差が生じる可能性があります。 add_size = file_size_new - file_size を計算して、ファイル サイズが変更されるかどうかを確認し、変更がある場合は、ファイル ポインターを指定した位置に移動し、新しく追加された内容を出力し、file_size の値を new_file_size に更新します。 usleep(50000)、1/20 秒間スリープします。 コード
  1. #!/usr/bin/env php
  2. if(2 != count($argv)){
  3. fwrite(
  4. STDERR,
  5. "呼び出し形式エラー! 形式 ./tail ファイル名を使用してください" .PHP_EOL
  6. );
  7. return 1;
  8. }
  9. $file_name = $argv[1];
  10. define("MAX_SHOW", 8192);
  11. $file_size = 0;
  12. $file_size_new = 0;
  13. $add_size = 0 ;
  14. $ignore_size = 0;
  15. $fp = fopen($file_name, "r");
  16. while(1){
  17. clearstatcache();
  18. $file_size_new = filesize($file_name);
  19. $add_size = $file_size_new - $ file_size;
  20. if($add_size > 0){
  21. if($add_size > MAX_SHOW){
  22. $ignore_size = $add_size - MAX_SHOW;
  23. $add_size = MAX_SHOW;
  24. fseek($fp, $file_size + $ignore_size);
  25. }
  26. fwrite(
  27. STDOUT,
  28. fread($fp, $add_size)
  29. );
  30. $file_size = $file_size_new;
  31. }
  32. usleep(50000);
  33. }
  34. fclose($fp);
コードをコピー

ここの最初の行の #!/usr/bin/env php のコード実装は、実行可能ファイル php がシステム PATH で検索されることを実行可能ファイルに伝えます。これの利点は、移植性が高いことです。

2016-02-22 11:28:51 改善

PHP 公式マニュアルを確認したところ、fseek 関数はここで改善できることがわかりました。この関数は、オフセット ポインターのタイプを示す 3 番目のパラメーターも受け入れます。これは、先頭からのオフセットを設定することもできます。現在の位置からのオフセットを示す SEEK_CUR に変更されるため、これは fseek($fp, $ignore_size, $ignore_size); に変更されます。 以下が結果です

PHP は Linux コマンドテールを実装します

PHP、Linux、テール

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。