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

Wie kann ich feststellen, welcher Prozess eine Datei unter Linux geöffnet hat?

Ich möchte feststellen, welcher Prozess Eigentümer einer Sperrdatei ist. Bei den Sperrdateien handelt es sich einfach um eine Datei mit einem bestimmten Namen, die erstellt wurde.

Wie kann ich also feststellen, welcher Prozess eine bestimmte Datei unter Linux geöffnet hat? Vorzugsweise wäre ein einzeiliger Typ oder eine bestimmte Linux-Tool-Lösung optimal.

Antworten (4)

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

Auf den meisten Linux-Systemen erfüllt lsof NAME die Aufgabe:

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

Sie können dafür auch fuser verwenden:

~> 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

Eine geöffnete Datei ist keine Sperre, denn wenn jeder Prozess zuerst prüfen muss, ob die Datei geöffnet ist, und nicht fortfahren muss, wenn sie geöffnet ist, oder sie erstellen/öffnen muss, wenn sie es nicht ist, dann können zwei Prozesse sehr wohl gleichzeitig prüfen, beide feststellen, dass sie nicht geöffnet ist, und sie dann beide erstellen oder öffnen.

Um eine Datei als Sperre zu verwenden, muss der Prüf- und Sperrvorgang ein einziger unterbrechungsfreier Vorgang sein. Sie können dies in einem Unix-Dateisystem erreichen, indem Sie eine Datei im Nur-Lese-Modus erstellen und sie zum Entsperren entfernen. Wenn die Datei existiert (und schreibgeschützt ist), schlägt die Dateierzeugung fehl, so dass Sie die Prüf- und Sperroperation in einer einzigen atomaren Operation erhalten.

Wenn Ihr Sperrprozess ein Shell-Skript ist, das als Daemon läuft, können Sie diesen Effekt erreichen, indem Sie umask verwenden, eine Einstellung pro Prozess, die die Berechtigungen festlegt, mit denen neue Dateien erstellt werden:

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

Dies schreibt auch die PID des besitzenden Prozesses in die Datei, was Ihr anderes Problem löst: cat /var/lock/foo


Was die spezielle Frage “Welche Prozesse haben diese Datei geöffnet? ”, kann dies nützlich sein, wenn Sie ein Dateisystem unmounten wollen, dies aber nicht können, weil ein Prozess eine Datei geöffnet hat. Wenn Ihnen diese Befehle nicht zur Verfügung stehen, können Sie /proc als root fragen:

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

oder, als sterblicher Benutzer:

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

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

Ich stellte fest, dass die Verwendung der akzeptierten Antwort nicht die Prozesse auflistete, die mein Verzeichnis ( ubuntu 14.04 ) verwendeten.

Am Ende verwendete ich lsof (Liste offener Dateien) und griff auf die Ausgabe zu, um den anstößigen Prozess zu finden:

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