参考资料





先来了解下什么是/proc

Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、 改变内核设置的机制。


/proc 是一个虚拟的文件系统:

/proc 文件系统是一种内核和内核模块用来向进程 (process) 发送信息的机制 (所以叫做 /proc)。这个伪文件系统让你可以和内核内部数据结构进行交互,获取 有关进程的有用信息,在运行中 (on the fly) 改变设置 (通过改变内核参数)。 与其他文件系统不同,/proc 存在于内存之中而不是硬盘上。如果你察看文件 /proc/mounts (和 mount 命令一样列出所有已经加载的文件系统),你会看到其中 一行是这样的:

1
2
[root@localhost ~] # grep proc /proc/mounts
proc /proc proc rw,relatime 0 0


/proc 是由内核控制的,所以没有所谓挂载proc的设备,/proc主要是存放内核控制的状态信息,所以大部分这些信息的逻辑位置位于内核控制的内存。对 /proc 进行 一次 'ls -l' 可以看到大部分文件都是 0 字节大的;不过察看这些文件的时候,确 实可以看到一些信息。这怎么可能?这是因为 /proc 文件系统和其他常规的文件系 统一样把自己注册到虚拟文件系统层 (VFS) 了。然而,直到当 VFS 调用它,请求 文件、目录的 i-node 的时候,/proc 文件系统才根据内核中的信息建立相应的文件 和目录。


DAC17958FE2A4BFBA22DC2DAEC194210

查看/proc 文件系统, 我们可以通过如:“cat”、“less”、“more”等命令来查看,当然了可以配合一些管道命令有如“grep”、“awk”、“sed”等来选取数据

当编辑程序试图打开一个虚拟文件时,这个文件就通过内核 中的信息被凭空地 (on the fly) 创建了。这是一些我从我的系统中得到的一些有趣 结果:

cpu信息文件 "/proc/cpuinfo"

CC174A4AB4EC410ABE4D7E1884E4D349

执行cat查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
[root@localhost proc] # cat /proc/cpuinfo
processor: 0
vendor_id: GenuineIntel
cpu family: 6
model: 58
model name: Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz
stepping: 9
cpu MHz: 2195.013
cache size: 6144 KB
physical id : 0
siblings: 3
core id : 0
cpu cores: 3
apicid: 0
initial apicid: 0
fpu: yes
fpu_exception: yes
cpuid level: 13
wp: yes
flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts xtopology tsc_reliable nonstop_tsc aperfmperf unfair_spinlock pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes xsave avx hypervisor lahf_lm ida arat epb xsaveopt pln pts dts
bogomips: 4390.02
clflush size: 64
cache_alignment: 64
address sizes: 40 bits physical, 48 bits virtual
power management:
processor: 1
vendor_id: GenuineIntel
cpu family: 6
model: 58
model name: Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz
stepping: 9
cpu MHz: 2195.013
cache size: 6144 KB
physical id : 0
siblings: 3
core id : 1
cpu cores: 3
apicid: 1
initial apicid: 1
fpu: yes
fpu_exception: yes
cpuid level: 13
wp: yes
flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts xtopology tsc_reliable nonstop_tsc aperfmperf unfair_spinlock pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes xsave avx hypervisor lahf_lm ida arat epb xsaveopt pln pts dts
bogomips: 4390.02
clflush size: 64
cache_alignment: 64
address sizes: 40 bits physical, 48 bits virtual
power management:
processor: 2
vendor_id: GenuineIntel
cpu family: 6
model: 58
model name: Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz
stepping: 9
cpu MHz: 2195.013
cache size: 6144 KB
physical id : 0
siblings: 3
core id : 2
cpu cores: 3
apicid: 2
initial apicid: 2
fpu: yes
fpu_exception: yes
cpuid level: 13
wp: yes
flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts xtopology tsc_reliable nonstop_tsc aperfmperf unfair_spinlock pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes xsave avx hypervisor lahf_lm ida arat epb xsaveopt pln pts dts
bogomips: 4390.02
clflush size: 64
cache_alignment: 64
address sizes: 40 bits physical, 48 bits virtual
power management:
processor: 3
vendor_id: GenuineIntel
cpu family: 6
model: 58
model name: Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz
stepping: 9
cpu MHz: 2195.013
cache size: 6144 KB
physical id : 1
siblings: 3
core id : 0
cpu cores: 3
apicid: 4
initial apicid: 4
fpu: yes
fpu_exception: yes
cpuid level: 13
wp: yes
flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts xtopology tsc_reliable nonstop_tsc aperfmperf unfair_spinlock pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes xsave avx hypervisor lahf_lm ida arat epb xsaveopt pln pts dts
bogomips: 4390.02
clflush size: 64
cache_alignment: 64
address sizes: 40 bits physical, 48 bits virtual
power management:
processor: 4
vendor_id: GenuineIntel
cpu family: 6
model: 58
model name: Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz
stepping: 9
cpu MHz: 2195.013
cache size: 6144 KB
physical id : 1
siblings: 3
core id : 1
cpu cores: 3
apicid: 5
initial apicid: 5
fpu: yes
fpu_exception: yes
cpuid level: 13
wp: yes
flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts xtopology tsc_reliable nonstop_tsc aperfmperf unfair_spinlock pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes xsave avx hypervisor lahf_lm ida arat epb xsaveopt pln pts dts
bogomips: 4390.02
clflush size: 64
cache_alignment: 64
address sizes: 40 bits physical, 48 bits virtual
power management:
processor: 5
vendor_id: GenuineIntel
cpu family: 6
model: 58
model name: Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz
stepping: 9
cpu MHz: 2195.013
cache size: 6144 KB
physical id : 1
siblings: 3
core id : 2
cpu cores: 3
apicid: 6
initial apicid: 6
fpu: yes
fpu_exception: yes
cpuid level: 13
wp: yes
flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts xtopology tsc_reliable nonstop_tsc aperfmperf unfair_spinlock pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes xsave avx hypervisor lahf_lm ida arat epb xsaveopt pln pts dts
bogomips: 4390.02
clflush size: 64
cache_alignment: 64
address sizes: 40 bits physical, 48 bits virtual
power management:

上述大部分的信息十分清楚地给出了这个系 统的有用的硬件信息。有些 /proc 的文件是经过编码的,不同的工具可以被用来解释 这些编码过的信息并输出成可读的形式。这样的工具包括:'top', 'ps', 'apm' 等。


我们试试一些有趣的命令,

查看逻辑CPU个数:

1
cat /proc/cpuinfo | grep 'processor' | wc -l


CC38750F50E64C8997165D647195172F


查看物理CPU个数:

1
cat /proc/cpuinfo | grep 'physical id' | sort | uniq | wc -l



1B1E7371E72B4A479550CC9597AC9493


查看每个物理CPU中Core的个数:

1
cat /proc/cpuinfo | grep 'cpu cores' | wc -l


99D335BF41AF4110908C67A11C5922EC


感觉还不错吧?通过这样我们可以获取一些关于这台计算机的一些配置信息等,由此可以针对性进行分析优化。

得到有用的系统/内核信息

proc 文件系统可以被用于收集有用的关于系统和运行中的内核的信息。下面是一些重要 的文件:

  • /proc/cpuinfo - CPU 的信息 (型号, 家族, 缓存大小等)

  • /proc/meminfo - 物理内存、交换空间等的信息

  • /proc/mounts - 已加载的文件系统的列表

  • /proc/devices - 可用设备的列表

  • /proc/filesystems - 被支持的文件系统

  • /proc/modules - 已加载的模块

  • /proc/version - 内核版本

  • /proc/cmdline - 系统启动时输入的内核命令行参数

proc 中的文件远不止上面列出的这么多。想要进一步了解的读者可以对 /proc 的每一个 文件都'more'一下或读参考文献[1]获取更多的有关 /proc 目录中的文件的信息。我建议 使用'more'而不是'cat',除非你知道这个文件很小,因为有些文件 (比如 kcore) 可能 会非常长。


举个例子,查看内核的版本
2206A2F81C6B450A8B4D0F331BFAA5B2

可以看到上面的信息几乎和“uname -a”输出的信息相同

C7BD844F4FA94F8EA8918B155B670766


获取有关运行中的进程的信息

/proc 文件系统可以用于获取运行中的进程的信息。在 /proc 中有一些编号的子目录。每个编号的目录对应一个进程 id (PID)。这样,每一个运行中的进程 /proc 中都有一个用它的 PID 命名的目录。这些子目录中包含可以提供有关进程的状态和环境的重要细节信息的文件。让我们试着查找一个运行中的进程。

在这里我让vim程序在后台运行

执行

1
ps -aef | grep vim

22EDA55A5FAC4CD7BFEA32F9821F3C6C

我们看到了后台vim程序的pid号是 "2015"

我们来看下在/proc中pid为2015的信息:

1B3FC0D6D33F4279B4CFA2440B2CA67D
3114CF46FCBC4E12887EACADC4FB965E
BE52A2D6EF9943D28153E717C83827B2


文件 "cmdline" 包含启动进程时调用的命令行。"envir" 进程的环境变两。 "status" 是进程的状态信息,包括启动进程的用户的用户ID (UID) 和组ID(GID) , 父进程ID (PPID),还有进程当前的状态,比如"Sleelping"和"Running"。 每个进程的目录都有几个符号链接,"cwd"是指向进程当前工作目录的符号 链接,"exe"指向运行的进程的可执行程序,"root"指向被这个进程看作是 根目录的目录 (通常是"/")。目录"fd"包含指向进程使用的文件描述符的链接。 "cpu"仅在运行 SMP 内核时出现,里面是按 CPU 划分的进程时间。


/proc/self 是一个有趣的子目录,它使得程序可以方便地使用 /proc 查找本进程地信息。/proc/self 是一个链接到 /proc 中访问 /proc 的进程所对应的 PID 的目录的符号链接。



通过 /proc 与内核交互


上面讨论的大部分 /proc 的文件是只读的。而实际上 /proc 文件系统通过 /proc 中可读写的文件提供了对内核的交互机制。写这些文件可以改变内核 的状态,因而要慎重改动这些文件。/proc/sys 目录存放所有可读写的文件 的目录,可以被用于改变内核行为。

/proc/sys/kernel - 这个目录包含反通用内核行为的信息。 /proc/sys/kernel/{domainname, hostname} 存放着机器/网络的域名和主机名。 这些文件可以用于修改这些名字。

我们通过了cat查看了/proc中的hostname与domainname的信息,然后通过 echo 把/proc中的信息修改并且/proc会在内核中做相对应的修改


97EEAE22CC8D4E3D81D8B9E949188E71

这样,通过修改 /proc 文件系统中的文件,我们可以修改主机名。很多其 他可配置的文件存在于 /proc/sys/kernel/。这里不可能列出所有这些文件, 读者可以自己去这个目录查看以得到更多细节信息。
另一个可配置的目录是 /proc/sys/net。这个目录中的文件可以 用于修改机器/网络的网络属性。比如,简单修改一个文件,你可以在网络 上瘾藏匿的计算机。


1
[root@localhost ~] # echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all


这将在网络上瘾藏你的机器,因为它不响应 icmp_echo。主机将不会响应其 他主机发出的 ping 查询。


要改回缺省设置,只要

1
[root@localhost ~] # echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all



结论

/proc 文件系统提供了一个基于文件的 Linux 内部接口。它可以用于确定系统 的各种不同设备和进程的状态。对他们进行配置。因而,理解和应用有关这个 文件系统的知识是理解你的 Linux 系统的关键。