0

2 つの別々の端末で次の操作を行いました。

1期:

バックグラウンドでファイルに書き込みを行っているプロセスを開始します。

└──> while true; do date >> log; sleep 1; done &
[1] 20604

バックグラウンドで実行されている最後のプロセスの PID を取得します。

└──> echo $!
20604

2学期:

書き込み中のファイルの内容を表示します。

└──> tail -f log
Thu May  7 18:48:20 CEST 2015
Thu May  7 18:48:21 CEST 2015
Thu May  7 18:48:22 CEST 2015
Thu May  7 18:48:23 CEST 2015
Thu May  7 18:48:24 CEST 2015
Thu May  7 18:48:25 CEST 2015
Thu May  7 18:48:26 CEST 2015
Thu May  7 18:48:27 CEST 2015

前期:

誰がファイルにアクセスしているかを確認します (リーダーしかいないことに注意してください)

└──> lsof log
COMMAND   PID  USER      FD   TYPE DEVICE SIZE/OFF   NODE NAME
tail    21038  wakatana   3r   REG    8,1     5340 797966 log

2番目の端末の後に終了し、空の出力をkill返した後:tail -flsof

└──> kill 21038
└──> lsof log
└──>

2学期:

その後tail -f、もう一度開始したところ、データがまだログ ファイルに書き込まれていることがわかりました。これは、一部のプロセスがまだログ ファイルに書き込み中であることを意味します。

└──> tail -f log
Thu May  7 18:52:33 CEST 2015
Thu May  7 18:52:34 CEST 2015
Thu May  7 18:52:35 CEST 2015
Thu May  7 18:52:36 CEST 2015
Thu May  7 18:52:37 CEST 2015
Thu May  7 18:52:38 CEST 2015
Thu May  7 18:52:39 CEST 2015
Thu May  7 18:52:40 CEST 2015

この場合、ファイルに書き込んでいるプロセスの不思議な PID を実際に知っています。それは PID 20604 なので、それを強制終了すると、ログ ファイルの成長が止まります。

私の質問は次のとおりです。

  1. lsof実際にログファイルに書き込んでいるプロセスが(繰り返し発行されても)表示されないのはなぜですか?20604 が属していることを理解してbashおり、ファイルに直接書き込みを行っているのは bash ではなく、 childdateです。しかし、lsofどちらbashも表示されませんでしdateた。
  2. PID 20604 がわからない場合はどうすればよいですか? では、書き込みプロセスをどのように追跡できますか?

PS: 使用したシェル: GNU bash、バージョン 4.2.37(1)-release (x86_64-pc-linux-gnu)

4

1 に答える 1

2

You have a classic engineering problem in the form of asynchronous sampling here.

Essentially, every long period of waiting time, a process will be very quickly spun up, write to a file, and then die.

Entirely asynchronous to that, you run lsof which looks for open files - but only effectively at one instant in time that probably will not match when the file is being written. (In actuality, lsof performs a multi-step operation, but there's probably only one-shot opportunity to catch any given writer).

It might be tempting to think that if you ran lsof enough times in a loop, you would eventually catch the writer in the act - and perhaps you will. However, depending on how your system's scheduler and I/O functionality works, it is possible that the writing process might be so brief as that there is never any chance for another process to run during it.

If you want a version of this which you can catch in the act, continue to have the generation spaced in time within a parenthesized subshell, but make the writing one consistent operation:

(while true; do date ; sleep 1; done) > log &

Or, if you want to try to catch brief events, you might look at the inotify mechanism (you can view its documentation with man inotify) Bear in mind that there is no identification of the actor, and when the actor is short lived like this you can't then go do an lsof type search to figure out who it was.

于 2015-05-07T17:43:35.307 に答える