115

Я хотел бы определить, какой процесс владеет файлом блокировки. Файлы блокировки - это просто файл с определенным именем, которое было создано.

Итак, как я могу определить, какой процесс имеет определенный файл, открытый в Linux? Предпочтительно однострочник или конкретный инструмент Linux будут оптимальными.

5 ответов5

138

На большинстве систем 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:~$
52

Вы также можете использовать 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
8

Открытие файла не является блокировкой, потому что, если каждый процесс должен сначала проверить, открыт ли файл, а не продолжить, если он есть, или создать или открыть его, если это не так, то два процесса вполне могут проверить одновременно, оба найдут что он не открыт, то создайте или откройте его.

Чтобы использовать файл в качестве блокировки, операция проверки и блокировки должна быть единственной непрерывной операцией. Вы можете добиться этого в файловой системе Unix, создав файл в режиме только для чтения и удалив его, чтобы разблокировать. Если файл существует (и доступен только для чтения), создание файла завершится неудачно, поэтому вы получаете проверку и блокировку в одной атомарной операции.

Если ваш процесс блокировки представляет собой сценарий оболочки, который будет работать как демон, вы можете получить этот эффект, используя 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
Что касается конкретного вопроса "Какие процессы открыли этот файл?msgstr ", это может быть полезно, когда вы хотите размонтировать файловую систему, но не можете, потому что в каком-то процессе открыт файл. Если у вас нет этих команд, вы можете задать /proc как root:

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

или, как смертный пользователь:

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

4

Если вы хотите узнать, какой дескриптор файла процесса ссылается на ваш файл без 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 <filename> от @fin, очевидно, является лучшим ответом, но для ответа на комментарий @ JoseLSegura, если его нет, вышеприведенным решением был мой ответ.

2

Я обнаружил, что при использовании принятого ответа не перечислялись процессы, которые использовали мой каталог (ubuntu 14.04).

В конце концов, я использовал lsof (список открытых файлов) и набрал его вывод, чтобы найти процесс, вызывающий ошибку:

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .