Вопрос: Как определить, какой процесс имеет файл в Linux?


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

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


111
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

47
2018-01-19 17:37



это было здорово, но чтобы использовать его в скрипте, мне пришлось проверять длину вывода. - chovy
что вы имеете в виду длина вывода? - Nathan Fellman
if [ fuser "$ file" `]; затем выйдите ` - chovy
фьюзер имеет странное поведение с кодами выхода. он возвращает 1 код выхода с двумя состояниями: A / некоторая внутренняя ошибка, проверенный файл не найден и т. д., B / no процесс открыл указанный файл. В ситуации A / некоторое сообщение об ошибке выводится на его вывод. К сожалению, когда файл доступен и открывается чем-то, вывод генерируется, но с кодом выхода 0. Было бы лучше, если фьюзер выйдет с тремя кодами, а не двумя, как в настоящее время. 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:~$

132
2018-01-19 16:18



А что, если у вас нет lsof? - JoseLSegura
@JoseLSegura: Я предполагаю, что вы достаточно находчивы для ответа «затем установите lsof», чтобы быть бесполезным для вас. Можете ли вы подробно остановиться на своей проблеме? Если у вас нет root, у вас, скорее всего, нет привилегий, чтобы узнать, открыт ли другой пользователь открытым файлом. - Michael Scheper


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

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

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

oldumask = $ (Umask)
umask 222 # создавать файлы, не поддающиеся
если echo $$> / var / lock / foo
тогда
    : блокировка выполнена успешно
еще
    : блокировка не выполнена
фи
umask $ oldumask
Это также записывает в файл файл PID владельца, который решает другую проблему: cat /var/lock/foo
Что касается конкретного вопроса «Какие процессы открывают этот файл?», Это может быть полезно, если вы хотите размонтировать файловую систему, но не можете, потому что у какого-либо процесса есть файл, открытый в нем. Если у вас нет этих команд, вы можете спросить /proc как корень:

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

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

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


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

1
2017-10-30 14:21