Linux文件描述符(文件句柄)

Linux文件描述符(文件句柄)表示进程打开的文件:

  • 查看指定 PID 打开的文件:

    # lsof -p 28290
    # lsof -a -p 28290
    # ls -l /proc/28290/fd
    
  • 使用 wc -l 计算打开文件数:

    lsof | wc -l
    
  • 列出内核内存的文件描述符:

    sysctl fs.file-nf
    

输出可能类似:

fs.file-nr = 7424    0       9223372036854775807

找出系统中占用FD最多的进程

当进程占用文件句柄过多,甚至达到了limits上限时,会导致应用程序无法正常工作,此时需要找出系统中占用文件句柄最多的进程:

列出系统中每个进程占用的文件句柄且按照打开FD数量排序
lsof | awk '{print $2}' | sort | uniq -c | sort -n

不过,我遇到过陈旧的操作系统 lsof 整个系统非常卡的情况,所以也可以改写如下脚本:

采用脚本列出系统中每个进程占用的文件句柄
ps aux | grep -v PID > ps.log
cat ps.log | awk '{print $2}' > pids
> pid_fd.log
for pid in `cat pids`;do
    fd_num=`sudo ls /proc/${pid}/fd | wc -l`
    echo "${pid},${fd_num}" >> pid_fd.log
done

获取指定PID的对应进程名:

列出指定进程ID对应的进程名
$ ps -p 79058
    PID TTY          TIME CMD
  79058 ?        00:00:30 qemu-system-x86

对于每个进程,可以独立检查其打开的文件:

列出指定进程打开的文件(句柄)
$ sudo lsof -p 79058
COMMAND     PID         USER   FD      TYPE             DEVICE SIZE/OFF    NODE NAME
qemu-syst 79058 libvirt-qemu  cwd       DIR                8,2     4096       2 /
qemu-syst 79058 libvirt-qemu  rtd       DIR                8,2     4096       2 /
qemu-syst 79058 libvirt-qemu  txt       REG                8,2 15791488 1840034 /usr/bin/qemu-system-x86_64
qemu-syst 79058 libvirt-qemu  DEL       REG               0,19          2955594 /[aio]
qemu-syst 79058 libvirt-qemu  mem       REG                8,2  4451632 1835291 /usr/lib/x86_64-linux-gnu/libcrypto.so.3
qemu-syst 79058 libvirt-qemu  mem       REG                8,2   170456 1835036 /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.5
...

实时监控指定进程打开的文件

如果要观察当前登陆实例(bash)的打开文件,可以结合 watch

watch -n 10 ls -l /proc/$$/fd

或者使用如下一个简单循环:

while:
do
 ls -l /proc/$$/fd
 sleep 10
done

或者还是使用 lsof

watch "lsof -p 1234"

参考