가장 큰 파일 설명자가 있는 프로세스를 찾는 방법은 무엇입니까?

가장 큰 파일 설명자가 있는 프로세스를 찾는 방법은 무엇입니까?

이 사이클에 무슨 문제가 있나요 for? 최대 파일 설명자 수를 소유한 프로세스를 찾으려고 합니다. for루프의 첫 번째 명령 ps aux | awk '{print $2}'은 프로세스 ID를 인쇄합니다. lsof: illegal process ID: PID출력의 첫 번째 줄이 이기 때문에 첫 번째 오류가 존재한다는 것을 알고 있지만 PID나머지 줄에서는 루프가 제대로 작동하면 안 되나요?

[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 ~]#

wc -l왜 반환 루프 대신 출력을 수행합니까 ?

아니면 가장 큰 파일 설명자를 가진 프로세스를 찾는 다른 방법이 있습니까?

답변1

문제는 do ... done섹션의 백틱입니다.

if; then ... fi쉘 스크립트를 작성할 때 블록( , 등)을 백틱 으로 묶을 필요가 없습니다 while; do ... done. 이렇게 하면 쉘이 백틱의 내용을 평가한 다음 해당 내용을 실행하게 됩니다. 따라서 백틱은 숫자(열린 파일 수)를 반환하고 해당 숫자를 실행하려고 하면 command not found.

그러므로 당신은 다음을 원합니다:

for i in `ps aux | awk '{print $2}'` ; do lsof -p $i | wc -l ; done

답변2

이것은 수년 전의 질문이지만 OP가 요청한 것은 다음을 사용하여 작동해야 합니다.

lsof | awk '{print $2}'| uniq -c| sort -n

그러면 PID당 열린 파일 수가 인쇄됩니다.

답변3

(val0x00ff와 Patrick이 지적했듯이 루프는 ``문제를 일으키는 명령 대체가 필요하지 않습니다. 이것은 문제를 해결하는 다른 방법을 찾는 것에 대한 두 번째 부분입니다.)

다음 명령을 사용하여 프로세스당 파일 설명자 수를 직접 표시할 수 있습니다 lsof.

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

이것은 대부분의 경우 작동합니다 lsof.

-Fpcn옵션은 각 줄을 표시하는 "기계 판독 가능" 형식을 출력합니다.

  • 앞에 "p"가 붙은 PID
  • 앞에 "c"가 있는 명령(이름) 출력
  • 앞에 "n"이 있는 파일 설명자 출력

awk 스크립트는 연관 배열("command[pid]"로 색인화됨)을 사용하여 파일 설명자 수를 추적하고 END{}입력 시 배열을 덤프합니다.

이러한 FD 개수는 일반적으로 다른 방법과 다르며, 개수가 실제 파일 설명자, 특히 메모리 매핑된 파일 이상이므로 일부 프로세스에서 숫자가 손실될 수 있다는 점 은 ps주목할 가치가 있습니다 ./proc/PID/fdlsof

실제 FD의 정확한 개수를 원하는 경우 "-d0-999999"를 추가하여 lsof숫자 파일 설명자로만 출력을 제한해야 합니다. 기술적으로 높은 숫자는 최소한 프로세스당 최대 FD 수여야 합니다. 또는 를 사용하여 이를 결정할 수 있지만 ulimit -n루트 getconf OPEN_MAX는 이를 변경할 수 있습니다. Linux에서는 에서 프로세스별 제한을 확인할 수 있으며 , 이를 상한 /proc/PID/limits으로 사용할 수 있습니다 ./proc/sys/fs/file-nr

Linux 시스템에서 파일 설명자를 계산하는 다른 저렴하고 재미있는 방법은 다음과 같습니다 /proc.

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

답변4

Linux 에서는 zsh다음과 같이 할 수 있습니다.

(){ pid=$1:t; } /proc/<->(nOe['(){ REPLY=$#; } $REPLY/fd/*(N)'])

$pid가장 많이 열린 파일 설명자가 있는 프로세스의 pid를 입력하세요 .

더 자세한 버전은 다음과 같습니다.

by_number_of_fds() {
  local process_dir=${1-$REPLY}
  local -a fds=( $process_dir/fd/*(N) )
  REPLY=$#fds
}
process_dirs_sorted_by_number_of_fds=(
  /proc/<->(O+by_number_of_fds)
)
pid_with_most_fds=$process_dirs_sorted_by_number_of_fds[1]:t

관련 정보