Como posso determinar qual processo tem um arquivo aberto no Linux?

112

Gostaria de determinar qual processo possui a propriedade de um arquivo de bloqueio. Os arquivos de bloqueio são simplesmente um arquivo com um nome específico que foi criado.

Então, como posso determinar qual processo tem um arquivo particular aberto no Linux? De preferência, um tipo de linha única ou uma solução de ferramenta Linux específica seria ideal.

    
por Danny 19.01.2010 / 17:08

5 respostas

49

Você também pode usar fuser para isso:

~> less .vimrc
# put in background
~> fuser .vimrc
.vimrc:              28135
~> ps 28135
  PID TTY      STAT   TIME COMMAND
28135 pts/36   T      0:00 less .vimrc
    
por 19.01.2010 / 18:37
134

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:~$
    
por 19.01.2010 / 17:18
8

Ter um arquivo aberto não é um bloqueio porque, se cada processo tiver que verificar se o arquivo está aberto primeiro e não prosseguir, ou se for criar ou abrir, se não estiver, dois processos poderão verificar simultaneamente , ambos acham que não está aberto, então ambos os criam ou abrem.

Para usar um arquivo como um bloqueio, a operação de verificação e bloqueio deve ser uma única operação ininterrupta. Você pode conseguir isso em um sistema de arquivos Unix criando um arquivo com o modo somente leitura e removendo-o para desbloquear. Se o arquivo existir (e for somente leitura), a criação do arquivo falhará, de modo que você obtenha check-and-lock em uma única operação atômica.

Se o processo de bloqueio for um script de shell que será executado como um daemon, você poderá obter esse efeito usando umask , uma configuração por processo que define as permissões com as quais novos arquivos 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
Isso também grava o processo de propriedade 'PID no arquivo, que resolve seu outro problema: cat /var/lock/foo No que diz respeito à pergunta específica "Que processos têm este arquivo aberto?", Isso pode ser útil quando você deseja desmontar um sistema de arquivos, mas não pode, porque algum processo tem um arquivo aberto nele. Se você não tiver esses comandos disponíveis, poderá perguntar a /proc como root:

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

ou, como usuário mortal:

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

    
por 20.01.2010 / 14:14
4

Se você quiser saber quais links de descritor de arquivo do processo exato para o seu arquivo sem lsof ou fuser - pesquisar por /proc :

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

Substitua $1 pelo nome de arquivo aberto que você está procurando. Você pode alterar o -printf para o que quiser ver ou canalizar para egrep -o '[0-9]+' | head -1 para usar com ps -Fp <pid> para as informações desse processo.

A resposta de $ lsof <filename> por @fin é a melhor resposta, obviamente, mas para responder ao comentário de @ JoseLSegura , se isso não estiver disponível, o solução acima foi a minha resposta.

    
por 15.11.2016 / 22:41
2

Descobri que usar a resposta aceita não listava os processos que estavam usando meu diretório (Ubuntu 14.04).

No final, usei lsof (listar arquivos abertos) e usei a saída para encontrar o processo problemático:

lsof | egrep "<regexp-for-your-file>"
    
por 30.10.2015 / 15:21

Tags