Linux:如何获取打开文件和文件描述符数量

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

一、linux的文件描述符

   文件描述符(FD:file descriptors),也可以说是文件句柄,当某个程序打开文件时,内核返回相应的文件描述符,程序为了处理该文件必须引用此描述符。文件描述符是一个正整数,用以标明每一个被进程所打开的文件和socket。最前面的三个文件描述符(0,1,2)分别与标准输入(stdin),标准输出(stdout)和标准错误(stderr)对应,后面打开的文件依此类推对应3、4…… 。

 

    linux系统对每个用户、进程、或整个系统的可打开文件描述符数量都有一个限制,一般默认为1024。当我们在系统或应用的日志中碰到“too many open files”错误记录时,这个其实不是说打开的文件过多,而是打开的文件描述符数量已达到了限制,这时就需要增加文件描述符的数量限制了。

 

1.1 获取系统打开的文件描述符数量

    [root@localhost ~]# cat /proc/sys/fs/file-nr 

    1216    0       197787

     //第一列 1216   :为已分配的FD数量

     //第二列 0          :为已分配但尚未使用的FD数量

     //第三列197787:为系统可用的最大FD数量

    已用FD数量=为已分配的FD数量 - 为已分配但尚未使用的FD数量。注意,这些数值是系统层面的。

 

1.2 获取进程打开的文件描述符数量

    [root@localhost ~]# pidof vim

      3253

    [root@localhost ~]# ll /proc/3253/fd

     总用量 0

    lrwx------. 1 test test 64  6月  8 18:11 0 -> /dev/pts/0

    lrwx------. 1 test test 64  6月  8 18:11 1 -> /dev/pts/0

    lrwx------. 1 test test 64  6月  8 18:11 2 -> /dev/pts/0

    lrwx------. 1 test test 64  6月  8 18:11 4 -> /home/test/.bash_history.swp

   

    //可以看到vim进程用了4个FD

 

1.3 更改文件描述符限制

    当碰到“too many open files”错误时,就需要增加文件描述符的限制数量,系统的默认文件描述符都比较大,一般来说,只需增加用户或进程的就可以了

    //用户或进程

    [root@localhost ~]# ulimit -n

     1024

    [root@localhost ~]# ulimit -n 10240

    [root@localhost ~]# ulimit -n

     10240 

注意,使用ulimit 命令更改后只是在当前会话生效,当退出当前会话重新登录后又会回到默认值1024,要永久更改可以修改文件 /etc/security/limit.conf,如

   [root@localhost ~]#vi /etc/security/limits.conf 

   加入 “abc hard nofile 10240”

   abc:用户名,即允许test使用ulimit命令更改FD限制,最大值不超过10240,更改后abc用户的每一个进程(以abc用户运行的进程)可打开的FD数量为10240个

   hard:限制类型,有soft/hard两种,达到soft限制会在系统的日志(一般为/var/log/messages)里面记录一条告警日志,但不影响使用。hard,达到这个限制,有日志且会影响使用。

   nofile:限制的内容,nofile - max number of open files

   1024 :值

更改后,退出终端重新登录,用ulimit看看有没有生效,如果没生效,可以在abc用户的.bash_profile文件加上 ulimit -n 10240 ,以使用户abc每次登录时都会将FD最大值更改为10240,如:

   [root@localhost ~]#echo "ulimit -n 10240" >> /home/abc/ .bash_profile

    10240

   [root@localhost ~]# su - abc

   [abc@localhost ~]$ ulimit -n

    10240

 

limit.conf文件里面本身已有很详细的使用方法,这个下次可以说说。

 

      //系统级别

 将整个操作系统可以使用的FD数量更改为51200

     [root@localhost ~]# echo "51200" > /proc/sys/fs/file-max

     [root@localhost ~]# cat /proc/sys/fs/file-nr

     1184    0       51200

像这样更改在系统重启后会恢复到默认值,要永久更改可以在sysctl.conf文件加上fs.file-max = 51200

如:

    [root@localhost ~]# echo "fs.file-max = 51200" >> /etc/sysctl.conf

二、获取打开的文件数量

linux的一切皆为文件,那么如何知道系统/应用打开了哪些或是多少个文件呢?很简单,用lsof命令就行了,lsof,list  open files的简写,可列出程序或系统正在使用的文件。

 

2.1 获取整个系统打开的文件数量

     [root@localhost ~]# lsof |wc -l

       1864

2.2 获取某个用户打开的文件数量 

    [root@localhost ~]# lsof -u test |wc -l

       15

2.3 获取某个程序打开的文件数量 

   [root@localhost ~]# pidof vim

      3253

    [root@localhost ~]# lsof -p 3253 |wc -l

      31

上面所示只是用lsof来显示已打开的文件数量,lsof的功能远不止这些,有兴趣可以man lsof看一下 

 

三、进程打开的文件描述符与文件

如前面说的,为什么说“too many open files”错误不是说打开的文件过多,而是打开的文件描述符数量已达到了限制,这个简单的可以用man ulimit就可得知

[abc@localhost ~]$   man ulimit 

//找到ulimit,可以看到下列一行

-n   The maximum number of open file descriptors (most systems do not allow this value to be set)

这行就说明了用ulimit -n xxx 更改的是文件描述符而不是文件的最大值。

 

 我们可以来测试一下:

  •  打开一个进程vim,获取vim打开的文件及文件描述符数量

[abc@localhost ~]$ lsof -p 3330 |wc -l //文件数量

31

[abc@localhost ~]$ ls /proc/3330/fd |wc -l  //文件描述符数量

4

[abc@localhost ~]$ killall -9 vim

[1]+  已杀死               vim .bash_profile

[abc@localhost ~]$ ulimit -n 20

  • 更改限制,并测试vim的运行情况

[abc@localhost ~]$ ulimit -n 20 //更改为20,即小于文件数量31

[abc@localhost ~]$ ulimit -n

20

[abc@localhost ~]$ vim .bash_profile //可看到vim可以正常打开文件

# .bash_profile

# Get the aliases and functions

if [ -f ~/.bashrc ]; then

        . ~/.bashrc

fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH

ulimit -n 10240

----------------------------------

[abc@localhost ~]$ ulimit -n 3    //更改为3,即小于FD数量4

[abc@localhost ~]$ ulimit -n

3

[abc@localhost ~]$ vim .bash_profile   

-bash: start_pipeline: pgrp pipe: Too many open files 

vim: error while loading shared libraries: libselinux.so.1: cannot open shared object file: Error 24

 

从上面可看到小于文件描述符的数值时即报“Too many open files”错误,那么这个应该可以说明这个“Too many open files”错误是是打开的文件描述符数量已达到了限制所引起的,跟打开的文件数量没有关系。

 

另用lsof可知道进程都打开了哪些文件和文件描述符:

[abc@localhost ~]$ lsof -p 3330

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME

vim     3555  abc  cwd    DIR  253,0     4096 923587 /home/abc

vim     3555  abc  rtd    DIR  253,0     4096      2 /

vim     3555  abc  txt    REG  253,0  1971360 287900 /usr/bin/vim

vim     3555  abc  mem    REG  253,0   155696    846 /lib64/ld-2.12.so

vim     3555  abc  mem    REG  253,0    26104 281208 /usr/lib64/libgpm.so.2.1.0

vim     3555  abc  mem    REG  253,0  1912928    847 /lib64/libc-2.12.so

vim     3555  abc  mem    REG  253,0    22536    852 /lib64/libdl-2.12.so

vim     3555  abc  mem    REG  253,0   145672    859 /lib64/libpthread-2.12.so

vim     3555  abc  mem    REG  253,0   598816    848 /lib64/libm-2.12.so

vim     3555  abc  mem    REG  253,0   124624    857 /lib64/libselinux.so.1

vim     3555  abc  mem    REG  253,0   113904    856 /lib64/libresolv-2.12.so

vim     3555  abc  mem    REG  253,0  1489600 406575 /usr/lib64/perl5/CORE/libperl.so

vim     3555  abc  mem    REG  253,0   142504     96 /lib64/libncurses.so.5.7

vim     3555  abc  mem    REG  253,0    34336    890 /lib64/libacl.so.1.1.0

vim     3555  abc  mem    REG  253,0    43392    869 /lib64/libcrypt-2.12.so

vim     3555  abc  mem    REG  253,0   387880    868 /lib64/libfreebl3.so

vim     3555  abc  mem    REG  253,0  1753952 271694 /usr/lib64/libpython2.6.so.1.0

vim     3555  abc  mem    REG  253,0    17520    886 /lib64/libutil-2.12.so

vim     3555  abc  mem    REG  253,0   138280    826 /lib64/libtinfo.so.5.7

vim     3555  abc  mem    REG  253,0    20280    887 /lib64/libattr.so.1.1.0

vim     3555  abc  mem    REG  253,0   116136    889 /lib64/libnsl-2.12.so

vim     3555  abc  mem    REG  253,0    61624     42 /lib64/libnss_files-2.12.so

vim     3555  abc  mem    REG  253,0    26050 265158 /usr/lib64/gconv/gconv-modules.cache

vim     3555  abc  mem    REG  253,0   124855 528606 /usr/share/vim/vim72/lang/zh_CN/LC_MESSAGES/vim.mo

vim     3555  abc  mem    REG  253,0   135533 528604 /usr/share/vim/vim72/lang/zh_CN.UTF-8/LC_MESSAGES/vim.mo

vim     3555  abc  mem    REG  253,0 99158752 264902 /usr/lib/locale/locale-archive

vim     3555  abc    0u   CHR  136,0      0t0      3 /dev/pts/0

vim     3555  abc    1u   CHR  136,0      0t0      3 /dev/pts/0

vim     3555  abc    2u   CHR  136,0      0t0      3 /dev/pts/0

vim     3555  abc    4u   REG  253,0     4096 923589 /home/abc/.bash_profile.swp 

可看到运行vim时,打开了很多个文件,但文件描述符只有后面四个。

本文转自博客园知识天地的博客,原文链接:Linux:如何获取打开文件和文件描述符数量,如需转载请自行联系原博主。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
27天前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
40 5
|
27天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
44 6
|
27天前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
66 6
|
28天前
|
监控 Linux Perl
Linux 命令小技巧:显示文件指定行的内容
在 Linux 系统中,处理文本文件是一项常见任务。本文介绍了如何使用 head、tail、sed 和 awk 等命令快速显示文件中的指定行内容,帮助你高效处理文本文件。通过实际应用场景和案例分析,展示了这些命令在代码审查、日志分析和文本处理中的具体用途。同时,还提供了注意事项和技巧,帮助你更好地掌握这些命令。
41 4
|
1月前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
55 2
|
1月前
|
缓存 监控 Linux
|
1月前
|
Linux Shell 数据库
文件查找是Linux用户日常工作的重要技能介绍了几种不常见的文件查找方法
文件查找是Linux用户日常工作的重要技能。本文介绍了几种不常见的文件查找方法,包括使用`find`和`column`组合、`locate`和`mlocate`快速查找、编写Shell脚本、使用现代工具`fd`、结合`grep`搜索文件内容,以及图形界面工具如`Gnome Search Tool`和`Albert`。这些方法能显著提升文件查找的效率和准确性。
48 2
|
1月前
|
Linux 数据库
linux 全局搜索文件
在 Linux 系统中,全局搜索文件常用 `find`、`locate` 和 `grep` 命令。`find` 根据文件名、类型、大小、时间戳等条件搜索;`locate` 通过预构建的数据库快速查找文件;`grep` 在文件中搜索特定文本,常与 `find` 结合使用。选择合适的命令取决于具体需求。
|
2月前
|
Linux 开发工具 Perl
Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
【10月更文挑战第20天】Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
44 4
|
2月前
|
运维 安全 Linux
Linux文件清空的五种方法总结分享
每种方法各有优势,选择最合适的一种或几种,可以极大提高您的工作效率。更多有关Linux系统管理的技巧与资源,欢迎访问,持续提升您的运维技能。
79 1