題 如何確定在Linux中打開文件的進程?


我想確定哪個進程擁有鎖文件的所有權。鎖文件只是一個具有已創建的特定名稱的文件。

那麼,我如何確定在Linux中打開特定文件的進程?優選地,單線程類型或特定Linux工具解決方案將是最佳的。


112
2018-01-19 16:08


起源




答案:


你也可以使用 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

49
2018-01-19 17:37



這很棒,但要在腳本中使用它我必須檢查輸出長度。 - chovy
你的意思是輸出長度是多少? - Nathan Fellman
if [ fuser“$ file”`];然後退出 - chovy
fuser與退出代碼有奇怪的行為。它返回1個具有兩種狀態的exitcode:A /某個內部錯誤,找不到檢查文件等,B / no進程打開指定文件。在情況A /其輸出中打印一些錯誤消息。不幸的是,當文件可用並通過某些東西打開時,會生成輸出,但退出代碼為0.如果fuser將以三個代碼退出,而不是當前的兩個代碼。 lsoft的解決方案有點差,因為這個工作起來比較慢。 - Znik
這基本上與模式相同 ls 如果出現錯誤(例如,指定了無效選項),則返回退出代碼2 要么 找不到文件(如果成功報告信息則為0)。 - Scott


在大多數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:~$

134
2018-01-19 16:18



如果你沒有lsof怎麼辦? - JoseLSegura
@JoseLSegura:我假設你足夠聰明的答案'然後安裝lsof'對你沒用。你能詳細說明你的問題嗎?如果您沒有root,則可能沒有priv,以確定是否有其他用戶無論如何都打開了該文件。 - Michael Scheper


打開文件不是鎖定,因為如果每個進程必須先檢查文件是否先打開而不是繼續進行,如果不是,則創建/打開它,如果不是,則可以同時檢查兩個進程,兩者都找到它沒有打開,然後創建或打開它。

要將文件用作鎖,檢查和鎖定操作必須是單個不間斷操作。您可以通過創建具有隻讀模式的文件並將其刪除以解鎖來在Unix文件系統中實現此目的。如果文件存在(並且是只讀的),則文件創建將失敗,因此您可以在單個原子操作中進行檢查和鎖定。

如果您的鎖定進程是將作為守護程序運行的shell腳本,則可以通過使用來獲得此效果 umask,每進程設置,用於設置創建新文件的權限:

oldumask = $(的umask)
umask 222#創建文件也不可寫入所有者
如果echo $$> / var / lock / foo
然後
    :鎖定成功
其他
    :鎖定失敗
科幻
umask $ oldumask
這也將擁有進程的PID寫入文件,這解決了您的另一個問題: cat /var/lock/foo
至於具體問題“哪個進程打開了這個文件?”,當你想要卸載文件系統但是因為某個進程中有一個文件打開時,這可能很有用。如果您沒有可用的命令,可以詢問 /proc 以root身份:

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

或者,作為一個凡人用戶:

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


8
2018-01-20 13:14



`ls -l'方法適用於Linux,但似乎不適用於CygWin:沒有關於文件鎖定的信息。你不知道怎麼解決?謝謝。 - Sopalajo de Arrierez
不,您不為鎖定創建只讀文件,因為當您的應用程序崩潰時,該文件仍然存在。在崩潰的應用程序是精神上後,強制用戶清理垃圾。 - polkovnikov.ph


如果您想知道哪個精確進程的文件描述符沒有鏈接到您的文件 lsof 要么 fuser  - 搜索通過 /proc

$ find /proc -regex '\/proc\/[0-9]+\/fd\/.*' -type l -lname "*$1*" -printf "%p -> %l\n" 2> /dev/null

更換 $1 使用您要搜索的開放文件名。你可以修改 -printf 無論你想看到什麼,或管道進入 egrep -o '[0-9]+' | head -1 用於 ps -Fp <PID> 對於該過程的信息。

$ lsof <文件名> @fin的回答顯然是最好的答案,但要回答 @ JoseLSegura的評論,如果沒有,上面的解決方案是我的回答。


4
2017-11-15 21:41





我發現使用接受的答案沒有列出使用我的目錄(ubuntu 14.04)的進程。

最後,我使用lsof(列出打開的文件)並grepped其輸出來查找有問題的進程:

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

2
2017-10-30 14:21