Versuchen Sie Folgendes:
ps aux | sed 1d | awk '{print "fd_count=$(lsof -p " $2 " | wc -l) && echo " $2 " $fd_count"}' | xargs -I {} bash -c {}
Ich habe dies verwendet, um die wichtigsten Filehandler-verbrauchenden Prozesse für einen bestimmten Benutzer (Benutzername) zu finden, bei denen kein lsof- oder Root-Zugriff vorhanden ist:
for pid in `ps -o pid -u username` ; do echo "$(ls /proc/$pid/fd/ 2>/dev/null | wc -l ) for PID: $pid" ; done | sort -n | tail
Schauen Sie sich den /proc/
an Dateisystem:
ls /proc/$pid/fd/ | wc -l
Um dies für alle Prozesse zu tun, verwenden Sie Folgendes:
cd /proc
for pid in [0-9]*
do
echo "PID = $pid with $(ls /proc/$pid/fd/ | wc -l) file descriptors"
done
Als Einzeiler (Filter durch Anhängen von | grep -v "0 FDs"
):
for pid in /proc/[0-9]*; do printf "PID %6d has %4d FDs\n" $(basename $pid) $(ls $pid/fd | wc -l); done
Als Einzeiler mit dem Befehlsnamen, sortiert nach der Anzahl der Dateideskriptoren in absteigender Reihenfolge (begrenzen Sie die Ergebnisse, indem Sie | head -10
anhängen ):
for pid in /proc/[0-9]*; do p=$(basename $pid); printf "%4d FDs for PID %6d; command=%s\n" $(ls $pid/fd | wc -l) $p "$(ps -p $p -o comm=)"; done | sort -nr
Dank an @Boban für diesen Nachtrag:
Sie können die Ausgabe des obigen Skripts in das folgende Skript leiten, um die zehn Prozesse (und ihre Namen) anzuzeigen, die die meisten Dateideskriptoren geöffnet haben:
...
done | sort -rn -k5 | head | while read -r _ _ pid _ fdcount _
do
command=$(ps -o cmd -p "$pid" -hc)
printf "pid = %5d with %4d fds: %s\n" "$pid" "$fdcount" "$command"
done
Hier ist ein anderer Ansatz, um die Top-Ten-Prozesse mit den meisten offenen fds aufzulisten, wahrscheinlich weniger lesbar, also stelle ich ihn nicht voran:
find /proc -maxdepth 1 -type d -name '[0-9]*' \
-exec bash -c "ls {}/fd/ | wc -l | tr '\n' ' '" \; \
-printf "fds (PID = %P), command: " \
-exec bash -c "tr '\0' ' ' < {}/cmdline" \; \
-exec echo \; | sort -rn | head