開いたファイルハンドルに影響を与えずに新しいファイルへのシンボリックリンクを「ロール」することは可能ですか?

開いたファイルハンドルに影響を与えずに新しいファイルへのシンボリックリンクを「ロール」することは可能ですか?

ローカルで開発中のアプリケーションは、現在のタイムスタンプでフォーマットされたファイルに出力を書き込みますapp-%Y%m%d.log

ターミナルウィンドウで現在のログを簡単に追跡できるように、今日のログを指すというcurrent.logシンボリックリンクを使用しました。

毎日の作業を開始したら、tailプロセスを終了し、今日のファイルへのシンボリックリンクを指定してからtail -f current.log

tail再起動せずにファイルハンドルの宛先を変更してシンボリックリンクの宛先を変更できますかtail

この「新しいタスクの開始」タスクを自動化するには、今日のファイルへのシンボリックリンクを指すようにcron'edスクリプトを設定するのが簡単です。しかし、既存のtailプロセスは、ターゲットが変更されたことを知らないようです。

答え1

定期的にファイルを閉じて再度開くことができないと不可能だと思います。 tail(または他のプログラム)がファイルを開くと、ファイルのinodeへのハンドルを取得します。この時点で、ファイル名とリンクは参照されなくなりました。これがファイルシステムからファイルを削除することができ、それを開くすべてのプログラムが機能し続ける理由です。 ;astプログラムがファイルを閉じたときにのみ、実際にディスクから削除されます。

更新:少なくともOS Xバージョンでは、ファイルが移動された場合にファイルを再度開くことができる-Fオプションが最後にあります。

答え2

最新のLinuxを使用している場合は、inotifywait次のものを使用できます。イノティファイツールパック。まだこれを行っていませんが、inotifywaitシェルスクリプトでシンボリックリンクをリセットし、tail -fシンボリックリンクで停止して再起動するために使用できるようです。シンボリックリンクを処理し、現在のログファイルのみを追跡することもできます。

inotifyを使用しない場合は、読み取るファイル名のinode番号が変更されたことを確認するために、尾などのプログラムを直接作成できます。この時点で、tail-likeプログラムは古いファイル記述子を閉じて、別のファイル名の新しいファイル記述子を取得できるようになりました。これは書くのが難しいプログラムであり、競合状態が発生しやすい。

答え3

あなたの説明によれば、テールプロセスを終了/再開するクローンジョブを実行して特定の状況を解決できるようです。ただし、通常(Mac OSを除く)tailはファイル内の場所(つまりバイトオフセット)を記憶します。さらに、オープンファイルハンドルはシンボリックリンクではなくターゲットファイルを指します。ファイルが開かれると、シンボリックリンクは読み取りプロセスとは関係ありません。変更があると、元のパスに基づいてファイルを再度開く機能があるかもしれませんが、ほとんどの実装ではこれを行いません。

答え4

プログラムがファイルを開くと、ファイルが移動または削除されても同じファイルにアクセスし続けます。 (開いているファイルを削除すると、そのファイルの名前のみが削除されます。ファイルは—インデックスノード- 開いているプロセスがないと、実際に削除されます。 )

一部のプログラムは、開いているファイルに問題があるかどうかを監視します。たとえば、古典的なプログラムはtail -f同じファイルに印刷行を追加します。いくつかの最新の実装(GNU、FreeBSD、NetBSD、OSX)には、tail -F同じ名前の新しいファイルが所定の位置に移動されたかどうかを検出し、新しいファイルから読み取りを開始するこの機能があります。 。マルチテールこれを行うことも可能です(実行multitail --retry)。

あなたはそれを使用することができます通知するファイルが変更されたかどうかを検出するためのLinuxのインターフェイスまたは他のuniceの同等のインターフェイス。 Linuxでは、inotifywaitコマンドの使用

関連情報