我注意到,如果文件被重命名,lsof
则会显示新名称。
为了测试它,创建了一个python
脚本:
#!/bin/python
import time
f = open('foo.txt', 'w')
while True:
time.sleep(1)
看到lsof
重命名后:
$ python test_lsof.py &
[1] 19698
$ lsof | grep foo | awk '{ print $2,$9 }'
19698 /home/bfernandez/foo.txt
$ mv foo{,1}.txt
$ lsof | grep foo | awk '{ print $2,$9 }'
19698 /home/bfernandez/foo1.txt
我想这可能是通过号码inode
。为了测试这一点,我创建了该文件的硬链接。但是,lsof
仍然显示原来的名称:
$ ln foo1.txt foo1.link
$ stat -c '%n:%i' foo*
foo1.link:8429704
foo1.txt:8429704
$ lsof | grep foo | awk '{ print $2,$9 }'
19698 /home/bfernandez/foo1.txt
而且,如果我删除原始文件,lsof
即使仍然存在指向该文件的现有硬链接,也会将该文件列为已删除:
$ rm foo1.txt
rm: remove regular empty file ‘foo1.txt’? y
$ lsof | grep foo | awk '{ print $2,$9,$10 }'
19698 /home/bfernandez/foo1.txt (deleted)
所以最后...
我的问题
使用什么方法lsof
来跟踪打开的文件描述符,使其能够:
- 跟踪文件名更改
- 不知道现有的硬链接
答案1
您假设
lsof
使用内核名称缓存中的索引节点是正确的。在Linux平台下,路径名由Linux文件系统提供/proc
。硬链接的处理在常问问题:
3.3.4 为什么 lsof 不报告“正确的”硬链接文件路径名?
当 lsof 报告带有硬链接的文件的最右边路径名组件时,该组件可能来自内核的名称缓存。由于将打开的文件连接到内核名称缓存的密钥对于每个不同命名的硬链接可能是相同的,lsof 可能只报告所有打开的硬链接文件的一个名称。有时这在旁观者看来是“正确的”;有时不会。请记住,对内核重要的文件标识键是设备号和节点号,并且它们对于所有硬链接名称都是相同的。
事实上,完全显示已删除的节点也是 Linux 所特有的(以及 Solaris 10 的更高版本,根据相同的说法)常问问题)。