CentOS 7下lsof查询用户/进程打开文件结果不一致的问题及可靠查询方法咨询
CentOS 7下lsof查询用户/进程打开文件结果不一致的问题及可靠查询方法咨询
我遇到了一个可能是服务打开文件过多导致的问题,想查看该服务打开的文件并监控其变化。这是在CentOS 7系统上,我本来以为lsof能解决问题,但结果却让我摸不着头脑。
我的服务运行在名为service_user的用户下,这台机器上只有这个进程用这个用户。
我本以为用lsof -u service_user能得到该用户打开的文件,然后可以统计数量(先看总数,之后再看详情)。这个结果的数量对服务来说是合理的,完全看不出问题。但如果我用完整的lsof输出再过滤包含service_user的行,得到的文件数居然是前者的三个数量级!
[root ~]# lsof -u service_user | wc -l 1442 [root ~]# lsof | grep service_user | wc -l 1631673
我想统计机器上每个用户/进程打开的文件总数(确认我的进程是不是问题根源),尝试对lsof输出做简单处理,但发现用-u参数和不用时输出的列不一样——完整的lsof输出包含一个经常为空的时间列,导致提取列变得很麻烦。
我尝试用-F参数指定列,写了下面的脚本,把lsof -F pcLf的输出管道进去,想处理成便于分析的格式。结果和lsof | grep service_user的数量大致一致,比lsof -u service_user的结果大三个数量级:
#!/bin/bash IFS="" echo -e "PID\tCommand\tUser\tNumber of Files" OUTPUT= N=0 function add_tab() { OUTPUT+=$(echo -e "\t") } function write_out_and_reset() { if [[ -n "$OUTPUT" ]]; then echo "$OUTPUT$N" fi OUTPUT= N=0 } function add_value_to_output() { local LINE="$1" OUTPUT+="${LINE:1}" add_tab } while read -r LINE || [ -n "$LINE" ]; do case "${LINE:0:1}" in 'p') write_out_and_reset add_value_to_output "$LINE" ;; 'c') add_value_to_output "$LINE" ;; 'u') add_value_to_output "$LINE" ;; 'L') add_value_to_output "$LINE" ;; 'f') N=$((N+1)) ;; *) echo echo "Unknown line $LINE" ;; esac done write_out_and_reset
我的问题
- 如何可靠地查询某个进程或用户打开的文件数量?
- 如何可靠地统计机器上所有用户/进程各自打开的文件总数?
- 如何可靠地列出某个用户或进程打开的所有文件?
我也想弄明白为什么会出现上述结果不一致的情况,但最主要的是想知道该信任哪一种结果,这样才能继续排查我的实际问题。
备注:内容来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

