谁在写我的文件或者为什么 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,所以我可以杀死它,日志文件将停止增长。
我的问题是:
- 为什么
lsof
没有显示(即使重复发出)实际写入的进程
日志文件?我知道 20604 属于 bash
,它不是直接写入文件的 bash,而是子 date
。但是 lsof
既没有显示 bash
也没有显示 date
.
- 如果我不知道 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
类型的搜索以找出他是谁。
我在两个不同的终端上执行了以下操作:
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,所以我可以杀死它,日志文件将停止增长。
我的问题是:
- 为什么
lsof
没有显示(即使重复发出)实际写入的进程 日志文件?我知道 20604 属于bash
,它不是直接写入文件的 bash,而是子date
。但是lsof
既没有显示bash
也没有显示date
. - 如果我不知道 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
类型的搜索以找出他是谁。