谁在写我的文件或者为什么 lsof 没有显示作者但 reader 显示

Who is writing to my file or why lsof did not display the writer but reader do

我在两个不同的终端上执行了以下操作:

1 项:

启动正在后台写入文件的进程:

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

获取后台运行最后一个进程的PID:

└──> echo $!
20604

第二学期:

显示正在写入的文件内容:

└──> 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

第一学期:

检查谁在访问文件(注意只有reader)

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

在跟随 kill 后,第二个终端上的 tail -f 终止并且 lsof 返回空输出:

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

第二学期:

然后我再次启动 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,而是子 date。但是 lsof 既没有显示 bash 也没有显示 date.
  2. 如果我不知道 PID 20604 怎么办?那我要如何跟踪写作过程呢?

PS: shell 使用:GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)

你有一个经典的工程问题,形式为异步采样

基本上,每经过一段长时间的等待,一个进程就会很快启动,写入文件,然后死掉。

与此完全异步,您 运行 lsof 查找打开的文件 - 但仅在某一时刻有效,可能在文件正在打开时不匹配写。 (实际上,lsof 执行多步操作,但可能只有一次机会抓住 任何给定的 作者)。

你可能会想,如果你 运行 lsof 循环足够多次,你最终会抓住作者的表演 - 也许你会的。但是,根据您系统的调度程序和 I/O 功能的工作方式,写入过程可能会如此简短,以至于其他进程永远没有机会 运行。

如果你想要一个你可以在表演中捕捉到的版本,继续在带括号的子 shell 中按时间间隔生成,但使写入成为一个一致的操作:

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

或者,如果你想尝试捕获简短事件,你可能会查看 inotify 机制(你可以使用 man inotify 查看其文档)请记住,没有标识演员,当演员像这样短命时,您就无法进行 lsof 类型的搜索以找出他是谁。