Linux调试程序打开的文件句柄 -lsof命令使用tips

使用 lsof 命令

可以使用 命令查看特定进程打开的文件详情,帮助你找出哪些文件或连接没有被正确关闭

  • 列出所有打开的文件
lsof
  • 查找特定文件的打开情况:
lsof /path/to/your/file
  • 查找特定进程打开的文件:
lsof -p <PID>
  • 查找特定用户打开的文件:
lsof -u <username>
  • 查找特定命令打开的文件:
lsof -c <command>

命令输出示例和每列代表的信息

COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd   488 syslog    1w   REG    8,1     1151 268940 /var/log/syslog
  • COMMAND:打开文件的命令或进程名称。
  • PID:进程的进程标识符(PID)。
  • USER:启动进程的用户。
  • FD:文件描述符,表示文件在进程中的引用。常见值包括: cwd:当前工作目录 txt:程序代码 mem:内存映射文件
    NUMBER:实际的文件描述符编号,后面的字符表示文件的打开模式(r 读,w 写,u 读写)。
  • TYPE:文件类型,例如: REG:常规文件。
  • DIR:目录 FIFO:先进先出队列 CHR:字符设备。
  • DEVICE:文件所在的设备。 SIZE/OFF:文件大小或偏移量。
  • NODE:文件的节点号。 NAME:文件的名称或路径。

查找打开最多且未被关闭的文件

  1. 运行 lsof 命令并保存输出:
lsof -p 1234 > /tmp/lsof_output.txt
  1. 分析输出: 你可以使用 awk 或其他工具来统计每个文件的打开次数。例如:
awk '{print $9}' /tmp/lsof_output.txt | sort | uniq -c | sort -nr

这将输出每个文件被打开的次数,按降序排列。例如:

3 /dev/null
1 /home/user
1 /bin/bash
1 /lib/x86_64-linux-gnu/libtinfo.so.6.1

在这个示例中,/dev/null 文件被打开了 3 次,其他文件各被打开了一次。你可以根据这个信息找出打开最多且未被关闭的文件。

使用watch监控进程打开的文件个数

watch -n 1 "lsof -p <PID> | wc -l"

其中, 是你要监视的进程的进程ID。这个命令会每秒刷新一次,显示该进程当前打开的文件数。
使用“Ctrl + C”退出watch

可能解决的方案

  1. 增加系统允许的最大文件数:
    你可以使用 ulimit 命令来增加当前会话的最大文件数。例如:
ulimit -n 2048

这种方法在重启后会恢复默认值。如果需要永久修改,可以编辑 /etc/security/limits.conf 文件,添加如下内容:

 * soft nofile 4096
 * hard nofile 4096
  1. 调整系统文件最大数目
  • 要检查系统范围内的打开文件限制
cat /proc/sys/fs/file-max
  • 如果需要增加此限制,可以在 /etc/sysctl.conf 文件中添加以下行
fs.file-max = 100000
  • 使用以下命令应用新设置:
sudo sysctl -p

两个有用的debug脚本

  1. watchOpenFileSta.sh
#!/bin/bash
pid=$`
lsof -p $pid > "/tmp/lsof_$pid_output.txt"

lsof -p 1234 > /tmp/lsof_output.txt

  1. 总结文件打开的情况
#!/bin/bash
# Loop through all the provided files
for file in "$@"
do
    # Get the absolute path of the file
    absPath=$(realpath "$file")

    # Get the file name
    fileName=$(basename "$file")

    # Remove the file extension
    name="${fileName%.*}"

    # Get the current time in the format YYYYMMDD_HHMMSS
    currTime=$(date +"%Y%m%d_%H%M%S")

    # Use awk to extract the 9th column, sort, count unique values, and save the result to a timestamped file
    awk '{print $9}' "$absPath" | sort | uniq -c | sort -nr | tee "/tmp/fileOpenState_${name}_${currTime}.txt"
done

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值