このサイクルに何の問題がありますか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が指摘したように、ループは``
問題を引き起こすコマンドの置き換えを必要としません。これは問題を解決する別の方法を見つけることの2番目の部分です。)
次のコマンドを使用して、プロセスあたりのファイル記述子の数を直接表示できます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