我正在开发一个监视进程资源的应用程序,并在Linux中提供定期报告,但是我在提取每个进程的打开文件数方面遇到了问题.
如果我取出所有文件并根据它们的PID对它们进行分组并计算它们,这需要相当长的时间.
如何在Linux中为每个进程获取打开的文件数?
Alf*_*lfe 62
看一下/proc/文件系统:
ls /proc/$pid/fd/ | wc -l
Run Code Online (Sandbox Code Playgroud)
要对所有进程执行此操作,请使用以下命令:
cd /proc
for pid in [0-9]*
do
echo "PID = $pid with $(ls /proc/$pid/fd/ | wc -l) file descriptors"
done
Run Code Online (Sandbox Code Playgroud)
编辑:感谢@Boban的这个附录:您可以将上面脚本的输出传递到以下脚本中,以查看打开最多文件描述符的十个进程(及其名称):
...
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
Run Code Online (Sandbox Code Playgroud)
这是列出具有最开放fds的前十个进程的另一种方法,可能不太可读,所以我不把它放在前面:
find -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
Run Code Online (Sandbox Code Playgroud)
我用它来查找没有 lsof 或 root 访问权限的给定用户(用户名)的顶级文件处理程序消耗进程:
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
Run Code Online (Sandbox Code Playgroud)
\n\n如何获取 Linux 中每个进程的打开文件数?
\n
procpath query -f stat,fd\nRun Code Online (Sandbox Code Playgroud)\n如果您从根目录运行它(例如,在命令前加上 前缀sudo -E env PATH=$PATH),否则它只会返回/proc/{pid}/fd您可能列出的每个进程的文件描述符计数。这将为您提供一个大的 JSON 文档/树,其节点如下所示:
procpath query -f stat,fd\nRun Code Online (Sandbox Code Playgroud)\n字典的内容fd是每个文件描述符类型的计数。最有趣的可能是这些(有关更多详细信息,请参阅procfile.Fd描述或man fstat ):
reg\xe2\x80\x93 打开(常规)文件的计数sock\xe2\x80\x93 打开套接字的计数我是Procpath的作者,它是一个为 procfs 提供更好的界面以进行流程分析的工具。您可以记录进程树的 procfs 统计信息(在 SQLite 数据库中)并稍后绘制其中的任何一个。例如,对于打开文件描述符计数(所有类型的总和),我的 Firefox 进程树(根 PID 2468)如下所示:
\nprocpath --logging-level ERROR record -f stat,fd -i 1 -d ff_fd.sqlite \\ \n \'$..children[?(@.stat.pid == 2468)]\'\n# Ctrl+C\nprocpath plot -q fd -d ff_fd.sqlite -f ff_df.svg\nRun Code Online (Sandbox Code Playgroud)\n\n如果我只对特定类型的打开文件描述符(例如套接字)感兴趣,我可以将其绘制如下:
\nprocpath plot --custom-value-expr fd_sock -d ff_fd.sqlite -f ff_df.svg\nRun Code Online (Sandbox Code Playgroud)\n
尝试这个:
ps aux | sed 1d | awk '{print "fd_count=$(lsof -p " $2 " | wc -l) && echo " $2 " $fd_count"}' | xargs -I {} bash -c {}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
42166 次 |
| 最近记录: |