![Linux程序设计(第4版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/825/26211825/b_26211825.jpg)
3.10 /proc文件系统
我们在前面提到过,Linux将一切事物都看作为文件,硬件设备在文件系统中也有相应的条目。我们使用底层系统调用这样一种特殊方式通过/dev目录中的文件来访问硬件。
控制硬件的软件驱动程序通常可以以某种特定方式配置,或者能够报告相关信息。例如,一个硬盘控制程序可以被配置为使用一个特殊的DMA模式。一块网卡可以报告它是否协商了一个高速、双工的连接。
用于与设备驱动程序进行通信的工具在过去就已经十分常见。例如,hdparm可以用来配置一些磁盘参数,ifconfig可以报告网络统计信息。近年来,倾向于提供更一致的方式来访问驱动程序的信息。事实上,这种一致的方式甚至延伸到包括与Linux内核的各种元素的通信。
Linux提供了一个特殊的文件系统procfs,它通常以/proc目录的形式呈现。该目录中包含了许多特殊文件用来对驱动程序和内核信息进行更高层的访问。只要应用程序有正确的访问权限,它们就可以通过读写这些文件来获得信息或设置参数。
/proc目录中的文件会随系统的不同而不同,当Linux版本中有更多的驱动程序和设施支持procfs文件系统时,该目录中就会包含更多的文件。在这里,我们将介绍一些/proc目录中常用的文件,并简单讨论它们的用途。
用来撰写本章内容的电脑上的/proc目录列表包括如下项目:
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0126_0002.jpg?sign=1739263168-VQxvCMIxx7eDmPKVWAZVl3Hn6nT1KYOQ-0-9d441f1b80d5cc2437b7913713503bda)
在多数情况下,只需直接读取这些文件就可以获得状态信息。例如,/proc/cpuinfo给出的是cpu的详细信息:
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0126_0003.jpg?sign=1739263168-KThrGRZEoBQKfZjlZHW3FfdcXmowDi12-0-4972efabceaf22ccdb2d07ba4f9975d4)
类似地,/proc/meminfo和/proc/version分别给出的是内存使用情况和内核版本信息:
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0127_0002.jpg?sign=1739263168-ar7ZckzWzXPCcIoS5ehvCX411Qd2Mx7n-0-0f87e8d13bc62e530680cf6d451a6bf7)
每次读取这些文件的内容时,它们所提供的信息都会及时更新。所以再读一次meminfo文件会给出最新的信息。
你可以通过特定内核函数获得更多的信息,它们位于/proc目录的子目录中。例如,你可以通过/proc/net/sockstat文件获得网络套接字的使用统计:
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0128_0001.jpg?sign=1739263168-4Ma9sA2yNRIONyJ6A06JmGdp2CUWfLrZ-0-56416917b82b17e2017a3d1cf9ca8989)
/proc目录中的有些条目不仅可以被读取,而且可以被修改。例如,系统中所有运行的程序同时能打开的文件总数是Linux内核的一个参数。它的当前值可通过读取/proc/sys/fs/file-max文件得到:
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0128_0002.jpg?sign=1739263168-aZk8V7lOkFMAgxyyBJpRCet8gAzA3EMZ-0-23c3b9b88434a86690c9bbcd45c7fe57)
这个值被设置为76593。如果你需要增大该值,则可以通过写同一个文件来实现。如果你正在运行一个需要同时打开很多文件的应用程序套件(例如,一个使用了很多表的数据库系统),你可能就需要这么做。
对/proc目录中的文件进行写操作需要超级用户的权限。你在修改数据时需要特别小心,写入不适当的值可能会引发严重的问题,比如系统崩溃和数据丢失。
如果要将系统范围的文件句柄限制增加为80000,你只需将新的上限值写入file-max文件即可:
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0128_0003.jpg?sign=1739263168-PyHCBObsYUFbUISXoAXnVCar6W7DevQV-0-2d5066240c27dc278ec38c45d146a472)
现在,当你再次读取该文件时,你就可以看到新设定的值:
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0128_0004.jpg?sign=1739263168-Vf55aVlYSZ88cd6RwXEjjV0h0Rq8sv92-0-b1586f4713942c3b3afbe7cb98818cf0)
/proc目录中以数字命名的子目录用于提供正在运行的程序的信息。你将在第11章中学习程序如何以进程的方式执行。
现在,你只需要知道每个进程都有一个唯一的标识符:一个在1~32000的数字。ps命令会给出当前正在运行进程的列表。例如,在本章正在编写的时候:
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0128_0005.jpg?sign=1739263168-7o1vA0SDGq4YF4RWvrYvD2UfE3sgEgs7-0-77c9fb90253a09c2f9b1087a585e64af)
你可以看到有几个正在运行bash shell的终端会话和一个正在运行ftp程序的文件传输会话。你可以通过查看/proc目录来获得更多关于ftp会话的细节。
ftp的进程标识符是9118,所以你需要查看/proc/9118来获得关于它的更多细节:
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0128_0006.jpg?sign=1739263168-MbNO9HuXXFFPTx4J4bWpW9b7eT0bgZ1K-0-582862905f4f755b6661b4e883426afb)
你可以看到各种特殊文件,它们可以告诉你该进程的相关信息。
从上面的输出中你可以知道程序/usr/bin/pftp正在运行,它的当前工作目录是/home/neil/BLP4e/chapter03。通过查看这个目录下的其他文件,你还可以看到启动它的命令行以及它的shell环境。cmdline和environ文件以一系列null终止的字符串来提供这些信息,所以你在查看它们时需要小心。我们将在第4章对Linux环境进行深入讨论。
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0129_0002.jpg?sign=1739263168-PDgqkgMdQKZh3MLbXzw7wru2wpLktU66-0-ef726a276582bf80188538b4cdfe001a)
你可以看到ftp是由命令行ftp 192.168.0.12启动的。
fd子目录提供该进程正在使用的打开的文件描述符的信息。这个信息在确定一个程序同时打开了多少文件时十分有用。每个打开的描述符都有对应的一个条目,条目名字与描述符的数字相匹配。在本例中,你可以看到ftp如我们所预期的那样打开了0、1、2和3描述符。它们分别是标准输入、标准输出和标准错误描述符以及一个到远程服务器的连接。
![](https://epubservercos.yuewen.com/08DD0E/14642180305205206/epubprivate/OEBPS/Images/figure_0129_0003.jpg?sign=1739263168-kMPGWhXCk5v3z9bYpRVVobBBhIgo2exC-0-4cc552b6185b5f859d71f838db34720b)