跳转至

Linux 目录说明

Linux目录结构


  • 第一部份:FHS 要求必须要存在的目录
目录 说明
/bin 系统有很多放置可执行文件的目录,但/bin 比较特殊。因为/bin 放置的是在单人维护模式下还能够被操作的指令。 在/bin 下面的指令可以被 root 与一般帐号所使用,主要有:cat, chmod, chown, date, mv, mkdir, cp, bash 等等常用的指令。
/boot 这个目录主要在放置开机会使用到的文件,包括 Linux 核心文件以及开机菜单与开机所需配置文件等等。 Linux kernel 常用的文件名为:vmlinuz,如果使用的是 grub2 这个开机管理程序, 则还会存在/boot/grub2/这个目录喔!
/dev 在 Linux 系统上,任何设备与周边设备都是以文件的型态存在于这个目录当中的。 你只要通过存取这个目录下面的某个文件,就等于存取某个设备啰~ 比要重要的文件有/dev/null, /dev/zero, /dev/tty, /dev/loop_, /dev/sd_ 等等
/etc 系统主要的配置文件几乎都放置在这个目录内,例如人员的帐号密码档、 各种服务的启始档等等。一般来说,这个目录下的各文件属性是可以让一般使用者查阅的, 但是只有 root 有权力修改。FHS 建议不要放置可可执行文件(binary)在这个目录中喔。比较重要的文件有: /etc/modprobe.d/, /etc/passwd, /etc/fstab, /etc/issue 等等。另外 FHS 还规范几个重要的目录最好要存在 /etc/ 目录下喔:/etc/opt(必要):这个目录在放置第三方协力软件 /opt 的相关配置文件 /etc/X11/(建议):与 X Window 有关的各种配置文件都在这里,尤其是 xorg.conf 这个 X Server 的配置文件。 /etc/sgml/(建议):与 SGML 格式有关的各项配置文件 /etc/xml/(建议):与 XML 格式有关的各项配置文件
/lib 系统的函数库非常的多,而/lib 放置的则是在开机时会用到的函数库, 以及在/bin 或/sbin 下面的指令会调用的函数库而已。 什么是函数库呢?你可以将他想成是“外挂”,某些指令必须要有这些“外挂”才能够顺利完成程序的执行之意。 另外 FSH 还要求下面的目录必须要存在:/lib/modules/:这个目录主要放置可抽换式的核心相关模块(驱动程序)喔!
/media media 是“媒体”的英文,顾名思义,这个/media 下面放置的就是可移除的设备啦! 包括软盘、光盘、DVD 等等设备都暂时挂载于此。常见的文件名有:/media/floppy, /media/cdrom 等等。
/mnt 果你想要暂时挂载某些额外的设备,一般建议你可以放置到这个目录中。 在古早时候,这个目录的用途与/media 相同啦!只是有了/media 之后,这个目录就用来暂时挂载用了。
/opt 这个是给第三方协力软件放置的目录。什么是第三方协力软件啊? 举例来说,KDE 这个桌面管理系统是一个独立的计划,不过他可以安装到 Linux 系统中,因此 KDE 的软件就建议放置到此目录下了。 另外,如果你想要自行安装额外的软件(非原本的 distribution 提供的),那么也能够将你的软件安装到这里来。 不过,以前的 Linux 系统中,我们还是习惯放置在/usr/local 目录下呢!
/run 早期的 FHS 规定系统开机后所产生的各项信息应该要放置到 /var/run 目录下,新版的 FHS 则规范到 /run 下面。 由于 /run 可以使用内存来仿真,因此性能上会好很多!
/sbin Linux 有非常多指令是用来设置系统环境的,这些指令只有 root 才能够利用来“设置”系统,其他使用者最多只能用来“查询”而已。 放在/sbin 下面的为开机过程中所需要的,里面包括了开机、修复、还原系统所需要的指令。 至于某些服务器软件程序,一般则放置到/usr/sbin/当中。至于本机自行安装的软件所产生的系统可执行文件(system binary), 则放置到/usr/local/sbin/当中了。常见的指令包括:fdisk, fsck, ifconfig, mkfs 等等。
/srv srv 可以视为“service”的缩写,是一些网络服务启动之后,这些服务所需要取用的数据目录。 常见的服务例如 WWW, FTP 等等。举例来说,WWW 服务器需要的网页数据就可以放置在/srv/www/里面。 不过,系统的服务数据如果尚未要提供给网际网络任何人浏览的话,默认还是建议放置到 /var/lib 下面即可。
/tmp 这是让一般使用者或者是正在执行的程序暂时放置文件的地方。 这个目录是任何人都能够存取的,所以你需要定期的清理一下。当然,重要数据不可放置在此目录啊! 因为 FHS 甚至建议在开机时,应该要将/tmp 下的数据都删除唷!
/usr 第二层 FHS 设置,后续介绍
/var 第二曾 FHS 设置,主要为放置变动性的数据,后续介绍
  • 第二部份:FHS 建议可以存在的目录
目录 说明
/home 这是系统默认的使用者主文件夹(home directory)。在你新增一个一般使用者帐号时, 默认的使用者主文件夹都会规范到这里来。比较重要的是,主文件夹有两种代号喔:~:代表目前这个使用者的主文件夹 ~dmtsai :则代表 dmtsai 的主文件夹!
/lib<qual> 用来存放与 /lib 不同的格式的二进制函数库,例如支持 64 位的 /lib64 函数库等
/root 系统管理员(root)的主文件夹。之所以放在这里,是因为如果进入单人维护模式而仅挂载根目录时, 该目录就能够拥有 root 的主文件夹,所以我们会希望 root 的主文件夹与根目录放置在同一个分区中。
  • 第三部份:非 FHS 中定义的目录
目录 说明
/lost+found 这个目录是使用标准的 ext2/ext3/ext4 文件系统格式才会产生的一个目录,目的在于当文件系统发生错误时, 将一些遗失的片段放置到这个目录下。不过如果使用的是 xfs 文件系统的话,就不会存在这个目录了!
/proc 这个目录本身是一个“虚拟文件系统(virtual filesystem)”喔!他放置的数据都是在内存当中, 例如系统核心、行程信息(process)、周边设备的状态及网络状态等等。因为这个目录下的数据都是在内存当中, 所以本身不占任何硬盘空间啊!比较重要的文件例如:/proc/cpuinfo, /proc/dma, /proc/interrupts, /proc/ioports, /proc/net/* 等等。
/sys 这个目录其实跟/proc 非常类似,也是一个虚拟的文件系统,主要也是记录核心与系统硬件信息较相关的信息。 包括目前已载入的核心模块与核心侦测到的硬件设备信息等等。这个目录同样不占硬盘容量喔!

1 proc

/proc 目录 - 参考 - man-proc手册 - 在 linux 的根目录下存在一个/proc 目录,/proc 文件系统是一种虚拟文件系统,以文件系统目录和文件形式,提供一个指向内核数据结构的接口,通过它能够查看和改变各种系统属性.proc 目录通常情况下是由系统自动挂载在/proc 目录下,但是我们也可以自行手动挂载. - proc 目录下的大部分文件都是只读的,部分文件是可写的,我们通过这些可写的文件来修改内核的一些配置;

1.1 pid

/proc/pid 每一个 /proc/pid 目录中还存在一系列目录和文件,这些文件和目录记录的都是关于 pid 对应进程的信息.例如,在 /proc/pid 的目录下存在一个 task 目录,在 task 目录下又存在 task/tid 这样的目录,这个目录就是包含此进程中的每个线程的信息,其中的 tid 是内核线程的 tid; 通过 GETDENTS(2) 遍历/proc 就能够看到所有的 /proc/pid 的目录,当然通过 ls -al /proc 的方式也可以看到所有的信息.

每一个运行的进程都存在 pid,对应的在/proc 就存在一个/proc/pid 的目录,这个/proc/pid 目录也是一个伪文件系统.通常情况下每个/proc/pid 是属于运行进程的有效用户的 UID 和 GID.但是如果一个进程的 dumpable 属性的值大于1,从安全角度考虑,/proc/pid 的属性就是 root:root.

在 4.11 的内核版本之前,root:root 表示的是全局 UID 和 GID (在初始化的用户空间中的 UID 和 GID 都是 0).但是在 4.11 之后的内核版本,如果这个进程不是在初始化的用户空间中,它的 UID 却是 0,那么对应的/proc/pid 的权限也是 root:root.这就意味着在 docker 容器内,如果将进程的 PID 设置为 0,那么这个进程在容器内就是以 root 权限运行的.

进程的 dumpable 的属性可能因为如下的原先发生改变:

  • 通过 prctl 设置了 PR_SET_DUMPABLE 属性
  • 通过 /proc/sys/fs/suid_dumpable 文件修改

将 dumpable 重置为1,就可以恢复 /proc/[pid]/* 文件到进程有效的 UID 和 GID.

1.1.1 attr

/proc/pid/attr 是一个目录,这个目录下的文件的作用是为安全模块提供了 API.通过这些文件我们可以读取或者设置一些安全相关的选项.这个目录目前能够支持 SELinux,但是本意是为了能够支持更多的其他的安全模块.以下将会演示 SELinux 如何使用这些文件. PS: 只有内核开启了 CONFIG_SECURITY 选项,才能够看到这个目录.

1.1.1.1 current

/proc/pid/attr/current 这个文件的内容记录了当前进程的安全属性

在 SELinux 中,这个文件主要是用于得到当前进程的安全上下文.在 2.6.11 的内核之前,这个文件不能用来设置安全上下文 (写操作是不允许的),因为 SELinux 限制了进程安全转换为 EXECVE(2) (参考下方的 /proc/pid/attr/exec). 从 2.6.11 之后,SELinux 取消了这个限制.如果策略允许,SELinux 通过向这个文件写入来支持设置行为,虽然这个操作仅仅只是为了维护老的上下文和新的上下文的隔离.在 2.6.28 之前,SELinux 不允许多线程程序的线程通过这个值来设置安全上下文,因为这样会导致共享内存空间的县城的安全上下文不一致.从 2.6.28 之后,SELinux 取消了这个限制,开始支持多线程的设置方法.但是需要满足一定的条件,新的安全上下文需要绑定在老的上下文上,并且这个绑定关系是设置在策略当中的,同时新的安全上下文是老的安全上下文的一个子集.

1.1.1.2 exec

/proc/pid/attr/exec 这个文件代表给进程的 execve 的属性.

在 SELinux 中,有时候需要支持 role/domain 的转换,execve(2) 一般都是作为这种转换的首选,因为它提供了对进程的新的安全标签和状态继承的更好的控制.在 SELinux 中,如果重置了 execve(2),那么这个程序就会恢复到 execve(2) 所设置的状态.

1.1.1.3 fscreate

/proc/pid/attr/fscreate 这个文件代表进程与文件有关的权限,包括 open(2) mkdir(2) symlink(2) mknod(2)

SELinux 通过此文件能够保证以一个安全的方式创建文件,所以这里不会存在不安全的访问的风险 (在文件创建和文件属性设置).如果重置了 execve(2),那么程序也会被重置,包括程序所创建的文件.

1.1.1.4 keycreate

/proc/pid/attr/keycreate 如果进程将安全上下文写入此文件,那么所有创建 key 的行为都会被加载到此上下文中.更多的信息可以参考内核文件 Documentation/security/keys/core.rst(在 Linux3.0 和 Linux4.13 中文件是 Documentation/security/keys.txt 在 Linux3.0 之前是 Documentation/keys.txt

1.1.1.5 prev

/proc/pid/attr/prev 这个文件包含了进程在执行最后一个 execve (2) 的安全上下文.换句话说,这个文件的内容是 /proc/pid/attr/current 前一个值

1.1.1.6 socketcreate

/proc/pid/attr/socketcreate 如果一个进程向这个文件写入安全上下文,那么之后所有的 sockets 的创建行为都会在此进程上下文中;

1.1.2 autogroup

/proc/pid/autogroup 参考 sched(7)

1.1.3 auxv

/proc/pid/auxv 这个文件包含了在进程执行时,传递给进程的 ELF 的解释器的信息.这个文件的格式是一个无符号的 long 类型的 ID 加上每个 entry 的一个无符号的 long 类型,这最后的一个 entry 包含了两个零。参考 getauxval(3) `

1.1.4 cgroup

/proc/pid/cgroup 参考 cgroups(7)

1.1.5 clear_refs

/proc/pid/clear_refs 这是一个只写文件,只有进程的 owner 能够写. 只有下面这些值能够被写入:

  1. (Since Linux 2.6.22) 对进程所有的相关的页重置所有的 PG_Referenced 和 ACCESSED/YOUNG 位 (在 2.6.32 之前,任何的非零的值写入到此文件都是有效的)
  2. (Since Linux2.6.32) 对进程所有的匿名页重置所有的 PG_Referenced 和 ACCESSED/YOUNG 位
  3. (Since Linux2.6.32) 对进程所有的与文件相关的页重置所有的 PG_Referenced 和 ACCESSED/YOUNG 位.清除所有的 PG_Referenced 和 ACCESSED/YOUNG 提供了一个方法用于测量一个进程是有了多少内存.第一个可以参考的是/proc/[pid]/smaps 中的 VMAs 中的值.当清除了 PG_Referenced 和 ACCESSED/YOUNG 经过一段时间之后,再次测量这个值.
  4. (Since Linux3.11) 清空掉进程所有的页的 soft-dirty 位.通过向/proc/[pid]/clear_refs 清空,就能够知道哪些页是被污染了.
  5. 将 peak resident 重置为进程当前的 resident 的大小.

如果向/proc/pid/clear_refs 写入其他的任何值,不会有任何的效果; 只有当启用了 CONFGI_PROC_PAGE_MONITOR 的内核选项之,才会出现/proc/pid/clear_refs 文件

1.1.6 cmdline

/proc/pid/cmdline 这个只读文件是包含了进程执行的完整命令.如果此进程是一个僵尸进程,那么次文件没有任何的内容.

1.1.7 comm

/proc/pid/comm 此文件记录的是进程命令的 comm.在同一个进程中的不同线程的 comm 可能不同,可以访问 /proc/[pid]/task/tid/comm 获取进程中的每个线程的 comm. 通过向 /proc/self/task/tid/comm 写入就能够修改自己或者其他线程的 comm. 如果 comm 超过 TASK_COMM_LEN (16) 就会被截断.

这个文件的值可以通过 prctl(2) 的 PR_SET_NAME 和 PR_GET_NAME 的操作来设置和获取,通过 pthread_setname_np(3) 能够设置线程的 comm

1.1.8 coredump_filter

/proc/pid/coredump_filter 参考 core(5)

1.1.9 cpuset

/proc/pid/cpuset 参考 cpuset(7)

1.1.10 cwd

/proc/pid/cwd 这是一个当前的进程的工作目录.比如如果想要知道 pid 为 4451 的进程的工作目录,可以通过如下的命令查看:

cd /proc/4451/cwd; /bin/pwd  

在 bash 环境下,可能会出现/bin/pwd: couldn’t find directory entry in ‘..’ with matching i-node 的错误,这是因为 pwd 通常是 shell 内置的,需要使用这样的命令:

/proc/4451/cwd; pwd -P  

在多线程的程序中,如果主线程已经退出了,那么 cwd 的结果就是空. 取消或者是读取 (readlink(2)) 这个链接的内容的权限是由 ptrace 的访问模式 PTRACE_MODE_READ_FSCREDS 来控制的,参考 ptrace(2)

1.2 environ

/proc/pid/environ 这个文件包含的是当程序使用 execve 启动程序时的环境变量的值,其中的 entries 是通过 0x0 分割的,结尾是可能是 null.如果我们需要查询一个指定的进程的环境变量,我们可以采用如下的方法:

#cat /proc/4451/environ | tr '\000' '\n'  
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin  
HOSTNAME=commoncollection  
LANG=C.UTF-8  
JAVA_HOME=/docker-java-home/jre  
JAVA_VERSION=8u212  
JAVA_DEBIAN_VERSION=8u212-b01-1~deb9u1  
HOME=/root  

如果执行了 execve(2) 之后,进程调用了 putenv(3) 或者是直接修改 environ(7) ,那么 environ 变量的值是无法随之改变的. 更进一步,进程能够通过 prctl(2) 修改 PR_SET_MM_ENV_START 的值来修改这个文件所引用的内存位置. 读取这个文件的权限是由 ptrace(2) 的 PTRACE_MODE_READ_FSCREDS 来控制.

1.2.1 exe

/proc/pid/exe 在 Linux2.2 的内核及其之后,/proc/pid/exe 是直接执行的二进制文件的符号链接. 这个符号链接能够被取消. 尝试打开这个文件就相当与打开了二进制文件, 甚至可以通过重新输入/proc/pid/exe 重新运行一个对应于 pid 的二进制文件. 在一个多线程的程序中, 如果主线程已经退出了, 就无法访问这个符号链接.

在 Linux2.0 及其之前,/proc/pid/exe 是指向当前进程执行的二进制文件.采用 readlink() 读取返回如下的结果: [device]:inode

1.2.2 fd

/proc/pid/fd 这是一个子目录, 包含了当前进程打开的每一个文件. 每一个条目都是一个文件描述符, 是一个符号链接, 指向的是实际打开的地址.0 表示标准输入, 1 表示标准输出, 2 表示标准错误. 在多线程程序中, 如果主程序退出了, 那么这个文件夹将不能被访问.

程序能够使用文件名作为命令行参数,如果没有提供这样的参数,就不会从标准输入中读取信息也不会将标准输出发送到文件中.但是即使没有提供与文件相关的命令行参数,我们仍然可以使用标准的输出输入.例如我们可以通过 -i 和 -o 分别指向输入和输出文件.如下所是:

$ foobar -i /proc/self/fd/0 -o /proc/self/fd/1 ...  

在某些 UNIX 或者类似 UNIX 的系统中,/proc/self/fd/N 与/dev/fd/N 大致相同.大部分系统提供/dev/stdin,/dev/stdout,/dev/stderr 的符号链接,分别只想的是/proc/self/fd 中的 0,1,2.所以上述的命令也可以写为:

$ foobar -i /dev/stdin -o /dev/stdout ...  

1.2.3 fdinfo

/proc/pid/fdinfo/ 这是一个子目录, 包括了当前进程打开的所有的文件的文件描述符. 可以读取每一个文件描述符的内容一获取 i 信息. 如下所示:

$ cat  /proc/5040/fdinfo/99  
pos:    21718  
flags:  0100000  
mnt_id: 27  
  • pos 是十进制,显示当前文件的偏移量
  • flag 是八进制,显示文件的访问模式和文件状态标志. 该目录中的文件只有进程的所有者才可以读.

1.2.4 limits

/proc/pid/limits 该文件显示了每个进程的软中断, 硬中断和度量单位. 在 Linux2.6.35 之前, 这个文件仅仅只能被进程实际的 UID 访问. 在 26.36 之后, 该文件可以被系统中所有的用户读取.

1.2.5 maps

/proc/pid/maps 包含了当前进程映射的内存区域以及他们的访问权限. 文件格式如下:

address           perms offset  dev   inode   pathname  
08048000-08056000 r-xp 00000000 03:0c 64593   /usr/sbin/gpm  
08056000-08058000 rw-p 0000d000 03:0c 64593   /usr/sbin/gpm  
08058000-0805b000 rwxp 00000000 00:00 0  
40000000-40013000 r-xp 00000000 03:0c 4165    /lib/ld-2.2.4.so  
40013000-40015000 rw-p 00012000 03:0c 4165    /lib/ld-2.2.4.so  
4001f000-40135000 r-xp 00000000 03:0c 45494   /lib/libc-2.2.4.so  
40135000-4013e000 rw-p 00115000 03:0c 45494   /lib/libc-2.2.4.so  
4013e000-40142000 rw-p 00000000 00:00 0  
bffff000-c0000000 rwxp 00000000 00:00 0  
  • address,表示进程占用的地址.
  • perms, 表示一系列权限.r=read,w=write,x=execute,s=shared,p=private(copy on write)
  • offset, 表示文件偏移量
  • dev: 表示设备 (主要设备,次要设备)
  • inode: 表示设备上面的 inode 编号.如果是 0,表示没有索引节点与内存区域关联,就如同 BSS 段一样.
  • pathname,在 Linux2.0 之前,没有 pathname 字段.

1.2.6 mem

/proc/pid/mem 该文件可以通过 open, read, seek 访问进程的内存页.

1.2.7 mountinfo

/proc/pid/mountinfo 这个文件主要是包含了挂载信息. 文件内容结构如下:

36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue  
(1)(2)(3)(4)      (5)      (6)       (7)   (8) (9)     (10)            (11)  
  • mount ID,挂载点的唯一标识
  • parent ID,当前挂载点的父挂载点的 ID
  • major:minor, files 的 st_dev 的值
  • root: 文件系统的根挂载点
  • mount point: 相对于进程根目录的挂载点
  • mount options: 预挂载选项
  • options fields: tag:[value] 类型的字段
  • sparator: options fields 结束标志
  • file systemtype: 文件系统的名称,以 type[.subtype] 的方式命名
  • mount source: 文件特定信息
  • super options: 超级块选项

1.2.8 mounts

/proc/pid/mounts 列出在当前进程挂载空间下所有的已经挂载过的文件. 文件的格式通过 fstab 查看. 在 kernel 2.6.15 之后, 这个文件是论询式的. 在读取文件之后, 这个事件会导致 select 标记这个文件是可读的, 并且 pool () 和 epoll_wait () 会将此文件标记为遇到了错误.

1.2.9 mountstas

/proc/pid/mountstas 该文件会列举在当前进程挂载空间下的所有挂载点的详细信息, 包括统计信息, 配置信息. 文件格式如下:

device    /dev/sda7    mounted     on    /home with fstype ext3 [statistics]  
(             1          )               ( 2 )              (3 )      (4)  
  1. 载的设备名
  2. 挂载点
  3. 文件系统类型
  4. 可选的统计和配置信息.在 2.6.26 之后,仅 NFS 文件系统可以到处此字段信息

1.2.10 ns

/proc/pid/ns/ 这是一个子目录. 每一个子目录可以通过 setns 操作. 关于更多的操作, 参见 clone

1.2.10.1 ipc

/proc/pid/ns/ipc 将文件挂载在其他地方可以使 pid 指定的进程的 IPC 命名空间保持活动状态, 即使在当前命名空间的所有的进程全部都截止了. 打开次文件就会返回文件句柄. 只要文件保持打开状态, 那么 IPC 的命名空间就可以保持活动状态. 文件描述符可以通过 setns 传递.

1.2.10.2 net

/proc/pid/ns/net 将文件挂载在其他地方可以使 pid 指定的进程的网络命名空间保持活动状态, 即使在当前命名空间的所有的进程全部都截止了. 打开次文件就会返回文件句柄. 只要文件保持打开状态, 那么网络的命名空间就可以保持活动状态. 文件描述符可以通过 setns 传递.

1.2.10.3 uts

/proc/pid/ns/uts 将文件挂载在其他地方可以使 pid 指定的进程的 UTS 命名空间保持活动状态, 即使在当前命名空间的所有的进程全部都截止了. 打开次文件就会返回文件句柄. 只要文件保持打开状态, 那么 UTS 命名空间就可以保持活动状态. 文件描述符可以通过 setns 传递

1.2.11 numa_maps

/proc/pid/numa_maps 参见 numa

1.2.12 oom_adj

/proc/pid/oom_adj 这个方法用于决定在出现 OOM 的情况下, 哪个进程被杀掉. 内核使用该值对进程的 oom_score 的值进行设定,oom_score 的有效取值区间是 -17 至 15.-17 将会完全杀死这个进程. 正数会增加进程当 oom 时被杀掉的可能性, 负数会减小进程被 oom 杀掉的可能性. 该文件的默认值是 0.新进程会继承其父进程的 oom_adj 设置.只有具有 CAP_SYS_RESOURCE 权限的进程才能够更新此文件. 在 Linux2.6.36,推荐使用/proc/[pid]/oom_score_adj.

1.2.13 oom_score

/proc/pid/oom_score 该文件显示了如果内核出现 oom 情况时决定杀死该进程时的分数. 分数越高意味着进程越容易被杀掉.

1.2.14 oom_adj_score

/proc/pid/oom_adj_score 这个文件用于调整在内存不足时应该杀掉哪个进程的分数判断.

1.2.15 root

/proc/pid/root 该值可以用于 chroot 预先设定进程的根文件系统. 这个文件指向当前进程的根目录. 作业类似于前面说过的 exe fd/* 等等. 在多线程的程序中,如果主线程推出了此符号链接的内容将无法访问.

1.2.16 smaps

/proc/pid/smaps 这个文件显示了每个进程映射的内存消耗. 每一个内存消耗都有如下的设置:

08048000-080bc000 r-xp 00000000 03:02 13130      /bin/bash  
Size:               464 kB  
Rss:                424 kB  
Shared_Clean:       424 kB  
Shared_Dirty:         0 kB  
Private_Clean:        0 kB  
Private_Dirty:        0 kB  

第一行显示的信息与/proc/[pid]/maps 中的映射信息相同.剩下分别表示的是,映射的大小,RAM 中当前驻留的映射大小,映射中干净和脏共享页的大小以及映射中干净和脏共享私有页数. 只有在启用了 CONFIG_MMU 内核配置选项时,此文件才会存在.

1.2.17 stat

/proc/pid/stat 关于进程的状态信息. 主要是用于 ps 展示. 文件中的每一行的含义如下:

  1. pid %d 进程 PID
  2. comm %s 可执行文件的文件名
  3. state %c 进程的状态,使用 RSDZTW 其中一个值表示.R 表示正在运行,S 表示因为中断休眠,D 表示进程处于不可中断的睡眠, When a process will go to ‘D’ state?. Z 表示僵尸进程,T 表示正在被追踪或者停止,W 表示现在正在进行叶交换.
  4. ppid %d 父进程 PID
  5. grid %d 进程组 ID
  6. session %d 进程的 session id
  7. tty_nr %d 进程的控制终端
  8. tpgid %d 进程控制终端的前台进程 id
  9. minflt %n 进程因为不需要从磁盘加载内存页而造成的次要故障数
  10. cminflt %u 进程等待子进程造成的次要故障数
  11. majflt %lu 进程需要从磁盘加载内存页造成的故障数
  12. cmajflt %lu 进程等待子进程造成的故障数
  13. utime %lu 进程在用户模式下被调度的时间
  14. stime %lu 进程在内核模式下被调度的时间
  15. cutime %ld 进程在用户模式下等待子进程的时间
  16. cstime %ld 进程在内核模式下等待子进程的时间
  17. nice %ld 参见 setpriority 位于 19 到 -20 之间.
  18. num_threads %ld 当前进程的线程数量
  19. vsize %lu 使用的虚拟内存
  20. rss %ld resident set szie 的缩写,表示进程在实际内存中的页数,主要是包括了 text,data,栈,不包括没有加载到内存中或者已经被换出去的内存大小
  21. rsslim %lu 进程 rss 的限制

还有一些不常见的字段,就不做说明了

1.2.18 statm

/proc/pid/statm 提供内存的使用情况. 格式如下所示:

size       (1) total program size  
           (same as VmSize in /proc/[pid]/status)  
resident   (2) resident set size  
           (same as VmRSS in /proc/[pid]/status)  
share      (3) shared pages (i.e., backed by a file)  
text       (4) text (code)  
lib        (5) library (unused in Linux 2.6)  
data       (6) data + stack  
dt         (7) dirty pages (unused in Linux 2.6)  

1.2.19 status

/proc/pid/status 以更加可读的形式提供与 /proc/pid/stat/proc/pid/statm 一样的信息. 以下是示例.

$ cat /proc/$$/status  
Name:   bash  
State:  S (sleeping)  
Tgid:   3515  
Pid:    3515  
PPid:   3452  
TracerPid:      0  
Uid:    1000    1000    1000    1000  
Gid:    100     100     100     100  
FDSize: 256  
Groups: 16 33 100  
VmPeak:     9136 kB  
VmSize:     7896 kB  
VmLck:         0 kB  
VmHWM:      7572 kB  
VmRSS:      6316 kB  
VmData:     5224 kB  
VmStk:        88 kB  
VmExe:       572 kB  
VmLib:      1708 kB  
VmPTE:        20 kB  
Threads:        1  
SigQ:   0/3067  
SigPnd: 0000000000000000  
ShdPnd: 0000000000000000  
SigBlk: 0000000000010000  
SigIgn: 0000000000384004  
SigCgt: 000000004b813efb  
CapInh: 0000000000000000  
CapPrm: 0000000000000000  
CapEff: 0000000000000000  
CapBnd: ffffffffffffffff  
Cpus_allowed:   00000001  
Cpus_allowed_list:      0  
Mems_allowed:   1  
Mems_allowed_list:      0  
voluntary_ctxt_switches:        150  
nonvoluntary_ctxt_switches:     545  

1.2.20 task

/proc/pid/task 该目录包含的是进程中的每一个线程. 每一个目录的名字是以线程 ID 命名的 (tid). 在每一个 tid 下面的目录结构与 /proc/pid 下面的目录结构相同. 对于所有线程共享的属性, task/tid 子目录中的每个文件内容与 /proc/pid 目录中的相应文件内容相同. 例如所有线程中的 task/tid/cwd 文件和父目录中的 /proc/pid/cwd 文件内容相同, 因为所有的线程共享一个工作目录. 对于每个线程的不同属性, task/tid 下相应文件的值也不相同.

1.3 cmdline

/proc/cmdline :在引导时传递给内核的参数

1.4 cpuinfo

/proc/cpuinfo :cpu 和系统结构的信息. 常见信息包括 CPU 的数量以及常见的系统常数.

1.5 meminfo

/proc/meminfo 此文件包含了系统当前内存的使用信息. free 用来报告系统中可用内存和已使用内存 (物理内存和交换内存) 以及内核中共享内存和缓冲区的大小. 每一行都是以 参数名:参数值 显示. 格式如下所示:

$ cat /proc/$$/status  
Name:   bash  
State:  S (sleeping)  
Tgid:   3515  
Pid:    3515  
PPid:   3452  
TracerPid:      0  
Uid:    1000    1000    1000    1000  
Gid:    100     100     100     100  
FDSize: 256  
Groups: 16 33 100  
.......  

1.6 modules

/proc/modules :显示当前加载到系统中所有的模块.

1.7 mounts

/proc/mounts 在内核 2.4.19 之前, 这个文件会列举当前系统中挂载的所有的节点信息. 在 2.4.19 之后, 仅仅只会列举出当前进程在 mount 的命名空间下的挂载信息, 即/proc/self/mounts 的挂载信息, 参见 fstab

1.8 net

/proc/net 此目录下面个中文虚拟的文件系统, 主要是记录了系统中各种与网络有关的信息. 这个文件都是普通 ASCII 文件, 都可以通过 cat 的方式读取.

1.8.1 arp

/proc/net/arp 此文件主要是包含了用于地址解析的内核 ARP 表的信息. 示例如下:

IP address     HW type   Flags     HW address          Mask   Device  
192.168.0.50   0x1       0x2       00:50:BF:25:68:F3   *      eth0  
192.168.0.250  0x1       0xc       00:00:00:00:00:00   *      eth0  
  • IP address 是主机的 IPv4 的地址
  • HW type 是来自与 RFC826 的硬件类型的地址
  • Flags 是 ARP 结构中的内部标识 参见 /usr/include/linux/if_arp.h
  • HW address 是数据链路层的映射地址

1.8.2 dev

/proc/net/dev dev 虚拟文件系统显示网络状态的信息, 包括发送和接受的数据包的数量, 错误和冲突以及其他的统计信息, 这些信息也可以通过 ifconfig 查看. 示例如下:

Inter-|   Receive                                                |  Transmit  
face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed  
lo: 2776770   11307    0    0    0     0          0         0  2776770   11307    0    0    0     0       0          0  
eth0: 1215645    2751    0    0    0     0          0         0  1782404    4324    0    0    0   427       0          0  
ppp0: 1622270    5552    1    0    0     0          0         0   354130    5669    0    0    0     0       0          0  
tap0:    7714      81    0    0    0     0          0         0     7714      81    0    0    0     0       0  

1.8.3 raw

/proc/net/raw :存储的是 RAW 套接字表的信息

1.8.4 snmp

/proc/net/snmp: 保存的是 SNMP 代理的 IP,ICMP 以及 UDP 的管理信息

1.8.5 tcp

/proc/net/tcp :保存的是系统中的 TCP 表的信息

1.8.6 udp

/proc/net/udp :保存的是系统中的 UDP 表的信息

1.8.7 unix

/proc/net/unix :显示当前系统所有的 UNIX domain socket 以及它们的状态信息. 示例如下:

Num RefCount Protocol Flags    Type St Path  
0: 00000002 00000000 00000000 0001 03  
1: 00000001 00000000 00010000 0001 01 /dev/printer  
  • Num 是 kernle table slot number
  • Refcount 是使用这个套接字的用户数
  • Protocol 当前永远是 0
  • Flags 表示当前内部内核标志 用于表示套接字状态
  • Type 当前永远是 1
  • St 套接字内部状态
  • Path 是套接字绑定路径

1.9 stat

/proc/stat :内核/系统的信息

1.10 sys

/proc/sys :该目录下有很多的目录和子目录, 其中主要是记录了与内核变量相关的信息.

1.11 tid

/proc/tid: 每一个 /proc/tid 目录中还存在一系列目录和文件,这些文件和目录记录的都是有关线程 tid 对应的信息,这些信息与具体的 /proc/pid/task/tid 的目录相同,所记录的信息也是相同的.我们遍历/proc 时并不能看到 /proc/tid 的信息,同样通过 ls -al /proc 的方式也无法看到.但是虽然无法看到,但是却可以通过 cd /proc/tid 进入到这个线程的内部; 传统的通过 ps | grep tid 是无法看到信息的,通过 ps -T -p pid 的方式就能够看到 tid 的信息.

1.12 self

/proc/self :这是一个 link, 当进程访问此链接时,就会访问这个进程本身的 /proc/pid 目录,如下所示:

ls -al  /proc/self  
lrwxrwxrwx 1 root root 0 Jun  4 17:08 /proc/self -> 32193  

1.13 thread-self

/proc/thread-self :这是一个 link,当访问次链接时,就会访问进程的 /proc/self/task/tid 目录。

ls -al /proc/thread-self  
lrwxrwxrwx 1 root root 0 Jun  4 17:08 /proc/thread-self -> 32265/task/32265  

1.14 其它

/proc/[a-z]*, proc 下面还有许多其他的文件,记录了系统中的各种信息,Linux /proc、/dev Principle 这篇文章对 proc 目录下的文件进行了详细的说明.

2 usr

- 很多读者都会误会/usr 为 user 的缩写,其实 usr 是 Unix Software Resource 的缩写, 也就是“Unix 操作系统软件资源”所放置的目录,而不是使用者的数据啦!这点要注意。 FHS 建议所有软件开发者,应该将他们的数据合理的分别放置到这个目录下的次目录,而不要自行创建该软件自己独立的目录。

  • 第一部份:FHS 要求必须要存在的目录 |目录|说明| |---|---| |/usr/bin/|所有一般用户能够使用的指令都放在这里!目前新的 CentOS 7 已经将全部的使用者指令放置于此,而使用链接文件的方式将 /bin 链接至此! 也就是说, /usr/bin 与 /bin 是一模一样了!另外,FHS 要求在此目录下不应该有子目录!| |/usr/lib/|基本上,与 /lib 功能相同,所以 /lib 就是链接到此目录中的!| |/usr/local/|系统管理员在本机自行安装自己下载的软件(非 distribution 默认提供者),建议安装到此目录, 这样会比较便于管理。举例来说,你的 distribution 提供的软件较旧,你想安装较新的软件但又不想移除旧版, 此时你可以将新版软件安装于/usr/local/目录下,可与原先的旧版软件有分别啦! 你可以自行到/usr/local 去看看,该目录下也是具有 bin, etc, include, lib...的次目录喔!| |/usr/sbin/|非系统正常运行所需要的系统指令。最常见的就是某些网络服务器软件的服务指令(daemon)啰!不过基本功能与 /sbin 也差不多, 因此目前 /sbin 就是链接到此目录中的。| |/usr/share/|主要放置只读架构的数据文件,当然也包括共享文件。在这个目录下放置的数据几乎是不分硬件架构均可读取的数据, 因为几乎都是文字文件嘛!在此目录下常见的还有这些次目录:/usr/share/man:线上说明文档 /usr/share/doc:软件杂项的文件说明 /usr/share/zoneinfo:与时区有关的时区文件|
  • 第二部份:FHS 建议可以存在的目录 |目录|说明| |---|---| |/usr/games/|与游戏比较相关的数据放置处| |/usr/include/|c/c++ 等程序语言的文件开始(header)与包含档(include)放置处,当我们以 tarball 方式 (*.tar.gz 的方式安装软件)安装某些数据时,会使用到里头的许多包含档喔!| |/usr/libexec/|某些不被一般使用者惯用的可执行文件或脚本(script)等等,都会放置在此目录中例如大部分的 X 窗口下面的操作指令, 很多都是放在此目录下的。| |/usr/lib<qual>/|与 /lib<qual>/ 功能相同,因此目前 /lib<qual> 就是链接到此目录中| |/usr/src/|一般源代码建议放置到这里,src 有 source 的意思。至于核心源代码则建议放置到/usr/src/linux/目录下。|

3 var

- 如果/usr 是安装时会占用较大硬盘容量的目录,那么/var 就是在系统运行后才会渐渐占用硬盘容量的目录。 因为/var 目录主要针对常态性变动的文件,包括高速缓存(cache)、登录文件(log file)以及某些软件运行所产生的文件, 包括程序文件(lock file, run file),或者例如 MySQL 数据库的文件等等。

目录 说明
/var/cache/ 应用程序本身运行过程中会产生的一些暂存盘;
/var/lib/ 程序本身执行的过程中,需要使用到的数据文件放置的目录。在此目录下各自的软件应该要有各自的目录。 举例来说,MySQL 的数据库放置到/var/lib/mysql/而 rpm 的数据库则放到/var/lib/rpm 去!
/var/lock/ 某些设备或者是文件资源一次只能被一个应用程序所使用,如果同时有两个程序使用该设备时, 就可能产生一些错误的状况,因此就得要将该设备上锁(lock),以确保该设备只会给单一软件所使用。 举例来说,烧录机正在烧录一块光盘,你想一下,会不会有两个人同时在使用一个烧录机烧片? 如果两个人同时烧录,那片子写入的是谁的数据?所以当第一个人在烧录时该烧录机就会被上锁, 第二个人就得要该设备被解除锁定(就是前一个人用完了)才能够继续使用啰。目前此目录也已经挪到 /run/lock 中!
/var/log/ 重要到不行!这是登录文件放置的目录!里面比较重要的文件如/var/log/messages, /var/log/wtmp(记录登陆者的信息)等。
/var/mail/ 放置个人电子邮件信箱的目录,不过这个目录也被放置到/var/spool/mail/目录中! 通常这两个目录是互为链接文件啦!
/var/run/ 某些程序或者是服务启动后,会将他们的 PID 放置在这个目录下喔!至于 PID 的意义我们会在后续章节提到的。 与 /run 相同,这个目录链接到 /run 去了!
/var/spool/ 这个目录通常放置一些伫列数据,所谓的“伫列”就是排队等待其他程序使用的数据啦! 这些数据被使用后通常都会被删除。举例来说,系统收到新信会放置到/var/spool/mail/中, 但使用者收下该信件后该封信原则上就会被删除。信件如果暂时寄不出去会被放到/var/spool/mqueue/中, 等到被送出后就被删除。如果是工作调度数据(crontab),就会被放置到/var/spool/cron/目录中!

4 链接目录

  • /bin --> /usr/bin
  • /sbin --> /usr/sbin
  • /lib --> /usr/lib
  • /lib64 --> /usr/lib64
  • /var/lock --> /run/lock
  • /var/run --> /run