Como encontrar o processo com descritores de arquivos máximos?

2

O que há de errado com esse loop for ? Eu estou tentando encontrar qual processo tem o número máximo de descritores de arquivo. O primeiro comando no for loop ps aux | awk '{print $2}' imprime apenas os IDs do processo. Eu sei que o primeiro erro lsof: illegal process ID: PID está lá porque a primeira linha da saída é PID , mas o loop não deve funcionar bem para o resto das linhas?

[root@serv5 ~]# for i in 'ps aux | awk '{print $2}'' ; do 'lsof -p $i | wc -l' ; done
lsof: illegal process ID: PID
lsof 4.82
 latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
 latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
 latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
 usage: [-?abhlnNoOPRtUvVX] [+|-c c] [+|-d s] [+D D] [+|-f[gG]] [+|-e s]
 [-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+m [m]] [+|-M] [-o [o]] [-p s]
[+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [--] [names]
Use the ''-h'' option to get more help information.
-bash: 0: command not found
-bash: 22: command not found
-bash: 4: command not found
-bash: 4: command not found
-bash: 4: command not found
-bash: 4: command not found
^C
[root@serv5 ~]#

Por que está executando a saída de wc -l em vez de retornar ao loop?

Ou há outra maneira de encontrar o processo com o máximo de descritores de arquivo?

    
por Sree 21.10.2014 / 14:57

2 respostas

3

O problema são os backticks na sua seção do ... done .

Ao escrever o shell script, você não precisa encapsular blocos ( if; then ... fi , while; do ... done , etc) em backticks. Isso resulta no shell avaliando o conteúdo dos backticks e, em seguida, executando esse conteúdo. Portanto, os backticks estão retornando um número (o número de arquivos abertos) e, em seguida, tentando executar esse número, resultando em um command not found .

Assim você quer:

for i in 'ps aux | awk '{print $2}'' ; do lsof -p $i | wc -l ; done
    
por 21.10.2014 / 15:16
1

(Seu loop perdeu '' causando o problema via substituição de comando, como notado por val0x00ff e Patrick. Isto é para a segunda parte sobre encontrar outra maneira de resolver o problema.)

Você pode mostrar o número de descritores de arquivo por processo usando lsof diretamente:

lsof -Fpcn | nawk '
 /^p/ { pid=substr($0,2) }
 /^c/ { cmd=substr($0,2) }
 /^n/ { fd[cmd"["pid"]"]++ }
 END  { for (cc in fd) printf("%-20s %i\n",cc,fd[cc]) } ' | sort -n -k 2

Isso deve funcionar na maioria dos sistemas * nix com lsof .

A opção -Fpcn exibe um formato "legível por máquina" que marca cada linha:

  • PIDs com um "p" líder
  • saída de comando (nome) com um "c" principal
  • saída do descritor de arquivo com um "n" principal

O script awk monitora a contagem do descritor de arquivo usando uma matriz associativa (indexada por "comando [pid]") e despeja a matriz na END{} da entrada.

Estas contagens FD diferem frequentemente de outros métodos, notáveis ps ou /proc/PID/fd contagens porque lsof conta mais do que apenas descritores de arquivos reais, arquivos mapeados em memória, em particular, provavelmente irão lançar seus números para alguns processos. / p>

Se você quiser uma contagem precisa dos FDs reais, é necessário adicionar "-d0-999999" para limitar a saída lsof apenas aos descritores de arquivos numéricos. Tecnicamente, o número alto deve ser pelo menos o número máximo de FDs por processo, provavelmente pode determinar isso com ulimit -n ou getconf OPEN_MAX , mas o root pode mudar isso. No Linux, você pode inspecionar os limites de cada processo em /proc/PID/limits e pode usar /proc/sys/fs/file-nr como limite superior.

Outras formas baratas e alegres de contar descritores de arquivos em um sistema Linux com /proc :

(cd /proc; ls -d [0-9]* ) | while read pid; do set -- /proc/$pid/fd/*; echo $pid $#; done
ps axo "pid" | while [...]
    
por 21.10.2014 / 20:18