2010-01-19 16:08:15 +0000 2010-01-19 16:08:15 +0000
127
127

如何确定Linux中哪个进程有文件打开?

我想确定哪个进程拥有锁文件的所有权。锁文件只是一个已经创建的具有特定名称的文件。

那么,在Linux中如何确定哪个进程拥有某个文件的打开权呢?最好是采用一字型或特定的Linux工具方案,这才是最理想的。

答案 (4)

146
146
146
2010-01-19 16:18:03 +0000

在大多数Linux系统中,lsof NAME可以完成以下工作:

fin@r2d2:~$ lsof /home/fin
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 21310 fin cwd DIR 8,1 4096 5054467 /home/fin
lsof 21320 fin cwd DIR 8,1 4096 5054467 /home/fin
lsof 21321 fin cwd DIR 8,1 4096 5054467 /home/fin
fin@r2d2:~$
56
56
56
2010-01-19 17:37:11 +0000

你也可以用fuser来做这个:

~> less .vimrc
# put in background
~> fuser .vimrc
.vimrc: 28135
~> ps 28135
  PID TTY STAT TIME COMMAND
28135 pts/36 T 0:00 less .vimrc
9
9
9
2010-01-20 13:14:12 +0000

有一个文件被打开并不是一个锁,因为如果每个进程都要先检查文件是否打开,如果打开了就不进行,如果不打开就不创建/打开,那么两个进程可以同时检查,两个进程都发现文件没有打开,然后都创建或打开。在Unix文件系统中,你可以通过创建一个只读模式的文件,然后将其取出来解锁来实现。如果文件存在(而且是只读模式),那么文件创建就会失败,所以你可以在一次原子操作中得到检查和锁定。

如果你的锁定进程是作为守护进程运行的shell脚本,你可以通过使用umask来获得这个效果,这是一个按进程设置的设置,它可以设置新文件创建的权限:

oldumask=$(umask) umask 222 # create files unwritable to owner too if echo $$ \> /var/lock/foo then : locking succeeded else : locking failed fi umask $oldumask

这也会把拥有进程的PID写入文件中,这就解决了你的另一个问题:cat /var/lock/foo


至于具体的问题 “哪些进程有这个文件打开? ",当你想卸载一个文件系统,但因为某个进程有一个文件打开了,所以无法卸载时,这个命令会很有用。如果你没有这些命令,你可以以root身份询问/proc

ls -l /proc/*/cwd | grep '/var/lock/foo$'

,或者以凡人用户的身份询问:

ls -l /proc/*/cwd 2>/dev/null | grep '/var/lock/foo$'

2
2
2
2015-10-30 14:21:35 +0000

我发现使用接受的答案并没有列出正在使用我的目录(ubuntu 14.04)的进程。

最后,我使用lsof(list open files),并对其输出进行了grepped,找到了违规的进程:

lsof | egrep "<regexp-for-your-file>"