谁在写我的文件或者为什么lsof没有显示作者而读者做

时间:2015-05-07 17:35:04

标签: linux bash file-descriptor lsof

我在两个不同的终端上做了以下行动:

1s术语:

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

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

第一学期:

检查谁在访问该文件(请注意,只有读者)

└──> 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怎么办?我如何跟踪写作过程呢?
  3. PS:使用的shell:GNU bash,版本4.2.37(1)-release(x86_64-pc-linux-gnu)

1 个答案:

答案 0 :(得分:2)

这里有异步采样形式的经典工程问题。

基本上,每隔一段很长的等待时间,一个进程将很快旋转,写入文件,然后死掉。

完全异步,你运行lsof寻找开放文件 - 但只在一个时刻有效,在编写文件时可能不匹配。 (实际上,lsof执行了多步操作,但可能只有一次机会来捕获任何给定的编写者。)

如果你在一个循环中运行lsof足够的次数,你最终会在行为中抓住作者 - 也许你会这样做,这可能很诱人。但是,根据系统的调度程序和I / O功能的工作方式,编写过程可能非常简短,因为在此过程中永远不会有其他进程运行。

如果你想要一个你可以在行为中捕获的版本,继续在带括号的子shell中使时间间隔,但是使写入一致的操作:

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

或者,如果您想尝试捕捉简短事件,可以查看inotify机制(您可以使用man inotify查看其文档)请记住,没有演员的身份证明当演员这样短暂的时候,你就不能再进行lsof类型搜索来找出它是谁。