이 사이클에 무슨 문제가 있나요 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/fd
lsof
실제 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