Linux中的PROC文件系统说明

时间:2020-03-21 11:46:38  来源:igfitidea点击:

每个Linux用户在日常系统管理活动中都使用以下命令。

  • Ps
  • uptime
  • free
  • uname 等

上面提到的在长列表中很少。
这些命令提供给用户的信息量非常出色,并且始终是准确的。
但是这些信息从何而来。
关于这些命令的另一个最令人惊奇的事实是它们提供了实时数据。
这意味着每次我们运行命令时,输出都会略有不同。

这意味着它从本质上非常动态的地方获取信息,并且还从非常可靠的源获取信息,并且每次都提供真实的和更新的数据。

由于内核是维护系统以使资源可用于不同程序的系统,因此只有内核知道当前的资源利用率以及有关系统的其他当前状态。

因此,当诸如ps或者top之类的程序需要有关当前运行状态的详细信息时,应询问内核,因为它是获得准确结果的理想来源。

为了使事情变得更容易,proc文件系统被制成。
它提供了一种访问底层内核数据结构的机制。
它还有助于在运行时修改某些内核参数。

/proc文件系统是提供的一种机制,因此内核可以将信息发送到进程。
这是提供给用户的接口,用于与内核进行交互并获取有关系统上运行的进程的必需信息。
请不要忘记以下事实:/proc文件系统还允许我们即时更改某些参数(在当前运行的系统上即刻生效)。

/proc文件系统很好地记录在proc手册页中。
我们可以通过在Linux系统上运行以下命令来访问此文档。

#man proc

在手册页中我们会遇到的第一行是...

proc进程信息伪文件系统

手册页将其进一步描述为:proc文件系统是一个伪文件系统,用作内核数据结构的接口。
它通常安装在/proc上。
它大多数是只读的,但是有些文件允许更改内核变量。

现在,我们对什么是/proc文件系统有了一些了解,让我们看一下有关它的一些有趣事实。

  • PROC文件系统完全由内核管理,不像其他文件系统那样存储在磁盘上。
  • 其存储在内存(内存)中
    -/proc中的大多数文件大小为0字节。 (这很有趣)

最有趣的部分是,/proc文件系统中几乎所有文件的大小均为0字节。
令许多用户感到困惑的事实是,尽管它们的大小为0,但在查看时仍然包含数据。
这怎么可能?

由于称为VFS(虚拟文件系统),Linux能够处理许多不同类型的文件系统。
它就像一个单一的界面,可用于读取和写入不同类型的文件系统。
我在有关NFS的文章中介绍了一些VFS。
我们可以通过访问以下链接来阅读。

VFS为Linux内核提供了一个简单的界面来访问其下的不同文件系统。

内核也使用VFS访问/proc文件系统。
因此,当用户尝试访问/proc文件系统中的文件时,proc文件系统将借助内核中的信息来创建该文件的内容。
这就是列出目录/proc的原因,其中大多数目录显示为0个字节,但在访问目录时会动态填充。

让我们实际检查一下并理解它。
linux中有一个名为file的命令。
linux中的“文件”命令用于通过检查文件内容来确定文件的类型。
如果文件为空,它将为我们提供“文件为空”的输出。
让我们尝试使用file命令检查任何/proc文件的文件类型。

让我们通过查看/proc/meminfo的类型来检查这一点,该文件用于从内核中获取当前的内存信息。

root@workstation:~# file /proc/meminfo
/proc/meminfo: empty

看到了吗?
,输出显示文件为空。
但是,让我们尝试使用任何编辑器(如vi,cat或者更少)访问文件。

root@workstation:~# cat /proc/meminfo
MemTotal:         502712 kB
MemFree:           47672 kB
Buffers:           16136 kB
Cached:           110768 kB
SwapCached:            0 kB
Active:           357388 kB
Inactive:          48264 kB
Active(anon):     278804 kB
Inactive(anon):      332 kB

注意:我没有显示完整的输出,因为它很长

因此,当我们访问内容时,将从内核中填充当前值。
这就是为什么要从/proc内的文件获得最新,最准确的系统状态的原因。

前面我们看到proc手册页将proc定义为“进程信息伪文件系统”。
这是因为它包含有关所有当前正在运行的进程的详细信息。
让我们看一下/proc的目录列表

root@workstation:/proc# ll
total 4
dr-xr-xr-x 110 root       root                     0 Dec  8 17:06 ./
drwxr-xr-x  23 root       root                  4096 Nov 19 04:55 ../
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 1/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 10/
dr-xr-xr-x   9 whoopsie   whoopsie                 0 Dec  8 17:06 1020/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 11/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 1122/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 1123/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 1127/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 1128/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 1129/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 1153/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 12/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 1233/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 1290/
dr-xr-xr-x   9 root       root                     0 Dec  8 17:06 13/
dr-xr-xr-x   9 root       ubuntu                   0 Dec  8 17:07 1393/

我们可以在上面显示的目录列表中看到里面有很多带编号的目录。
这些目录用相应的PID编号。
例如,如果Apache进程以2334的PID号运行,那么我们将拥有一个文件夹/proc/2334.

这些目录最有趣的是,它们在进程启动和停止时动态地出现和消失。
每个以其各自的PID命名的目录都包含有关进程当前状态的详细信息。

让我们看看/proc中PID目录的内容是什么。
下面显示的是PID(nginx工作进程)目录的内容。

root@workstation:/proc/27140# ls
attr       cgroup      comm             cwd      fd      latency   map_files  mountinfo   net        oom_adj        pagemap      sched      smaps  statm    task
autogroup  clear_refs  coredump_filter  environ  fdinfo  limits    maps       mounts      ns         oom_score      personality  schedstat  stack  status   wchan
auxv       cmdline     cpuset           exe      io      loginuid  mem        mountstats  numa_maps  oom_score_adj  root         sessionid  stat   syscall

现在让我们讨论一下该PID目录中的一些重要文件的含义。
讨论所有这些都不在本文的讨论范围之内,我本人也需要首先了解它们才能写出它们:)

  • PID目录中的/proc/<pid>/exe文件指向该进程正在执行的原始exe。它通常是指向exe文件原始位置的符号链接。在我们的示例中,这是/usr/sbin/nginx,因为我们看到的是nginx工作进程目录。这由以下命令确认。
root@workstation:/proc/27140# ll exe
lrwxrwxrwx 1 www-data www-data 0 Dec 10 01:17 exe -> /usr/sbin/nginx*

-/proc/<pid>/cmdline:这包含用于启动进程的命令。当我们在最后一列使用ps命令时,将显示此信息。

root@workstation:/proc/27140# cat cmdline
nginx: master process /usr/sbin/nginx

-/proc/<pid>/fd /:此目录包含进程打开的文件描述符。当我们看到nginx进程时,它应该具有其日志文件,套接字文件(基本上是连接)等。让我们看一下fd目录的内容。

root@workstation:/proc/27140/fd# ll
lrwx------ 1 root root 64 Dec 10 01:18 10 -> socket:[41479]
lrwx------ 1 root root 64 Dec 10 01:18 11 -> socket:[41480]
lrwx------ 1 root root 64 Dec 10 01:18 12 -> socket:[41481]
lrwx------ 1 root root 64 Dec 10 01:18 13 -> socket:[41482]
lrwx------ 1 root root 64 Dec 10 01:18 14 -> socket:[41483]
l-wx------ 1 root root 64 Dec 10 01:18 2 -> /var/log/nginx/error.log
lr-x------ 1 root root 64 Dec 10 01:18 3 -> /proc/27137/auxv
lrwx------ 1 root root 64 Dec 10 01:18 4 -> socket:[41476]
l-wx------ 1 root root 64 Dec 10 01:18 5 -> /var/log/nginx/access.log

-/proc/<pid>/maps:此文件包含映射到进程的文件。在大多数情况下,此文件包含该进程使用的库文件(如.so文件)的列表。让我们看一个例子,说明我们的nginx进程在maps文件中包含的内容。

root@workstation:/proc/27140# cat maps
00400000-004ba000 r-xp 00000000 08:01 25127                              /usr/sbin/nginx
006b9000-006ba000 r--p 000b9000 08:01 25127                              /usr/sbin/nginx
006ba000-006ce000 rw-p 000ba000 08:01 25127                              /usr/sbin/nginx
006ce000-006dd000 rw-p 00000000 00:00 0
00e78000-00ed3000 rw-p 00000000 00:00 0                                  [heap]
7f46e882b000-7f46e8837000 r-xp 00000000 08:01 21884                      /lib/x86_64-linux-gnu/libnss_files-2.15.so
7f46e8837000-7f46e8a36000 ---p 0000c000 08:01 21884                      /lib/x86_64-linux-gnu/libnss_files-2.15.so
7f46e8a36000-7f46e8a37000 r--p 0000b000 08:01 21884                      /lib/x86_64-linux-gnu/libnss_files-2.15.so
7f46e8a37000-7f46e8a38000 rw-p 0000c000 08:01 21884                      /lib/x86_64-linux-gnu/libnss_files-2.15.so

-/proc/<pid>/status:此文件包含处理器和内存使用情况的详细信息。该文件还包含pid详细信息以及进程的状态(如休眠或者运行)。它还具有有关父进程,组ID,用户ID等的信息。

root@workstation:/proc/27140# cat status
Name:   nginx
State:  S (sleeping)
Tgid:   27138
Pid:    27138
PPid:   1
TracerPid:      0
Uid:    0       0       0       0
Gid:    0       0       0       0
FDSize: 64
Groups: 0
VmPeak:    76848 kB

注意:我没有显示上面显示的大多数命令的完整输出。

现在,让我们看一下/proc内除proc PID目录内容之外的其他重要文件。
我们现在将讨论的文件将为我们提供有关系统当前状态的详细信息。
报告过程状态,正常运行时间平均负载等的大多数命令都通过访问/proc内的文件来获取信息。
我们将如何确认?

我们可以通过运行Linux中可用的调试命令来确认这一点,该命令通常用于程序调试。
该命令称为strace。
Strace将向我们显示程序正在访问的文件列表。
输出非常不整洁,因为它显示了很多细节。
尝试运行以下命令,我们将了解到诸如uname,uptime,ps和top之类的命令使用/proc内的文件来获取详细信息。

#strace ps

另外,诸如正常运行时间之类的命令还会向我们显示当前的平均负载。
该细节是从下面的文件中获取的。

root@workstation# cat /proc/loadavg
0.00 0.01 0.05 1/115 27562

-/proc/meminfo:此文件包含正在运行的系统的当前内存详细信息。它将向我们显示有关内存使用情况的完整详细信息。就像缓存使用了多少,实际使用了多少一样。完整的内存和当前可用的内存等。free命令从此处显示内存详细信息。

root@workstation:/proc# cat meminfo
MemTotal:         502712 kB
MemFree:          197672 kB
Buffers:           10796 kB
Cached:           141996 kB
SwapCached:            0 kB
Active:           168432 kB
Inactive:          75304 kB
Active(anon):      90988 kB
Inactive(anon):      280 kB
Active(file):      77444 kB
Inactive(file):    75024 kB
Unevictable:           0 kB

-/proc/version:此文件包含linux和发行版的详细信息。

root@workstation:/proc# cat /proc/version
Linux version 3.8.0-29-generic (buildd@panlong) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #42~precise1-Ubuntu SMP Wed Aug 14 16:19:23 UTC 2013

-/proc/diskstats:此文件包含磁盘设备的详细信息。详细信息包括读取,写入,读取完成,写入完成,读取所花费的时间,写入的扇区等。这是iostats等命令从中获取其信息的文件。访问下面的链接以了解文件中的14个不同字段。

/proc/diskstats的内容文件

root@workstation:/proc# cat diskstats
   8       0 sda 48088 175 2460234 433304 43196 36838 2571832 1694864 0 497496 2127260
   8       1 sda1 47924 175 2458922 432540 36743 36838 2571832 1688772 0 491412 2120404

-/proc/modules:此文件包含系统上当前加载的内核模块的列表。如果为lsmod运行strace命令(该命令列出了内核中的当前模块列表),我们将看到它正在访问/proc/modules文件以获取详细信息。
-/proc/cpuinfo:包含与处理器有关的完整详细信息。该文件将为我们显示处理器标志,处理器速度,处理器型号名称等。
-/proc/filesystems:此文件显示内核当前支持的文件系统总数。该列表本身包含proc文件系统,作为内核支持的文件系统之一。但是它属于没有设备的特殊文件系统。

我建议在/proc目录中浏览更多文件,因为所有这些文件的解释都超出了我的讨论范围。
如果我们有任何有趣的信息,请不要忘记通过注释与我们分享。

现在,如前所述,/proc内有可以修改的文件(或者具有写许可权的文件。
)。
这是Linux内核向用户提供的一种机制,以便他们可以在运行时修改系统行为和内核参数。

修改/proc目录中的文件时,必须格外小心。
仅当我们知道自己在做什么时,才执行此操作,否则系统可能变得不稳定。
大多数文件接受布尔值或者预定义值。
因此,请勿编辑或者发送不可接受的值。

目录/proc/sys包含在运行时可写的文件。
这可以通过将所需的值重定向到该文件来完成。
让我们看一下/proc/sys/kernel中的一些文件。
该目录包含主机名,域名等。
-/proc/sys/kernel/hostname:系统的主机名
-/proc/sys/kernel/domainname:主机所属的域

当我们启动hostname命令时,其作用是将主机名写入文件/proc/sys/kernel/hostname文件中。
请记住以下事实:这种设置主机名的方式不会使其永久存在。

我们通过编辑/proc/sys /文件即时修改的所有内容都是临时的。
这意味着将在关机时刷新数据。
因此,要使其永久存在,我们需要修改sysctl参数或者其他相关的推荐位置。
例如,编辑/etc/sysconfig/network文件以使主机名永久化。

另一个可写的目录是/proc/sys/net/ipv4 /。
此目录包含所有可用于修改Linux系统的网络行为的文件。
大多数系统管理员必须熟悉此目录,因为此目录包含ip_forward文件,该文件已被修改以启用ip转发(以使Linux充当路由器)。

下面提到了该目录中一些有趣的文件。
-/proc/sys/net/ipv4/ip_forward:接受两个值,即1或者0。1表示启用了ip转发,而0表示禁用了它。要即时启用ip转发,可以运行以下命令。

echo 1 > /proc/sys/net/ipv4/ip_forward

-/proc/sys/net/ipv4/ipfrag_high_thresh:允许用于重组IP片段的最高内存。如果数据在发送时太大,则将其分解为不同的片段并发送。当达到此限制时,发送机必须重新发送这些片段。它以字节为单位。
-/proc/sys/net/ipv4/icmp_echo_ignore_all:这将忽略对主机的所有ping请求。它还具有0或者1的值。 0表示禁用,1表示启用。
-/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts:这将忽略icmp广播请求。
-/proc/sys/net/ipv4/ip_default_ttl:可以修改此文件以更改默认的TTL值。 TTL是生存时间,以源和目标之间的跳数为准。

下面提到/proc/sys/net/ipv4 /中的其他一些有趣的文件。

  • tcp_rmem
  • tcp_window_scaling
  • tcp_wmem

它们用于调整Linux中的TCP性能。

正如我之前所说,很难解释/proc中的所有文件。
因此,请在此目录中浏览更多文件以了解其用法。
另外,如果我们发现任何有趣的内容,也请不要忘记通过注释与我分享(这将有助于我以及我们的读者获得有关它们的更多信息)。

/proc内另一个有趣的目录是self目录(/proc/self)。
它始终是当前过程的符号链接。
这意味着,每次符号链接都不同时,如果在/proc/self目录中执行ls -l。
sym链接指向查看/proc/self目录的进程的进程目录(在本例中为ls -l进程)。

每次在/proc/self上运行ls -l时,ls -l是一个具有不同PID的不同进程,因此它将显示不同的符号链接。

关于Linux中/proc文件系统的一些要记住的要点

  • proc是一个特殊的文件系统,不与任何硬盘驱动器设备关联。
    -/proc内的文件不是真实文件,它们充当内核数据结构和过程信息的接口。由于它们不是真实文件,因此文件大小之类的属性不适用于它们(因此显示为零字节)
  • 在请求时,/proc文件中的内容将动态填充。因此,从/proc提取的数据是内核提供的最新数据。
  • 可以修改/proc中的Certian文件来更改正在运行的内核的行为。例如,/proc/sys /文件。
  • 大多数系统监视命令(例如ps,top,free等)都使用/proc /中的进程文件来获取信息。
  • 可以从/proc/<pid>目录获取正在运行的进程的完整详细信息。
  • 程序可以使用一个名为/proc/self的特殊目录,以查找有关其自身进程的详细信息。