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

Como posso determinar que processo tem um ficheiro aberto no Linux?

Gostaria de determinar que processo tem a propriedade de um ficheiro bloqueado. Os ficheiros lock-files são simplesmente um ficheiro com um nome específico que foi criado.

Então, como posso determinar que processo tem um ficheiro em particular aberto no Linux? De preferência, uma solução do tipo “one-liner” ou uma ferramenta específica para Linux seria a melhor solução.

Respostas (4)

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

Na maioria dos sistemas Linux lsof NAME faz o trabalho:

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

Também pode usar fuser para isto:

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

Ter um ficheiro aberto não é um bloqueio porque, se cada processo tem de verificar se o ficheiro está aberto primeiro e não proceder se está ou criar/abrir se não está, então dois processos podem muito bem verificar simultaneamente, ambos descobrem que não está aberto, depois ambos criam ou abrem.

Para utilizar um ficheiro como bloqueio, a operação de verificação e bloqueio tem de ser uma única operação ininterrupta. Pode conseguir isto num sistema de ficheiros Unix, criando um ficheiro com modo só de leitura e removendo-o para o desbloquear. Se o ficheiro existir (e for apenas de leitura), a criação do ficheiro falhará, pelo que obtém o check-and-lock numa única operação atómica.

Se o seu processo de bloqueio é um script shell que estará a correr como um daemon, pode obter este efeito usando umask, uma configuração por processo que define as permissões com que os novos ficheiros são criados:

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

Isto também escreve o PID do próprio processo no ficheiro, o que resolve o seu outro problema: cat /var/lock/foo


No que diz respeito à questão específica “Que processos têm este ficheiro aberto? ”, isto pode ser útil quando pretende desmontar um sistema de ficheiros mas não pode porque algum processo tem um ficheiro aberto nele. Se não tem esses comandos disponíveis, pode perguntar ao /proc como raiz:

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

ou, como utilizador mortal:

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

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

Descobri que utilizando a resposta aceite não listava os processos que estavam a utilizar o meu directório ( ubuntu 14.04 ).

No final, utilizei lsof (listar ficheiros abertos) e grepped its output to find the offending process:

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