linux 目录结构及其含义

首先介绍一下 linux 目录配置标准: FHS。 FHS: Filesystem Hierarchy Standard.

建立这个标准的主要目的是希望让用户可以了解到已安装软件通常放置于那个目录下,所以希望独立的软件开发商、操作系统制作者以及想要维护系统的用户,都能够遵循 FHS 标准。

1.根目录(/)的意义与内容

根目录是整个 linux 系统最重要的一个目录,所有的目录都是由根目录衍生出来的,根目录也与开机、还原、系统修复等操作有关。 FHS 标准建议: 根目录(/)所在分区应该越小越好,且应用程序所安装的软件最好不要与根目录放在同一个分区内,保持根目录越小越好。如此不但性能较好,根目录所在的文件系统也较不容易发生问题。 查看 (/) 的文件结构如下:

1.1 /bin 目录

放置内容: 系统的可执行文件目录,linux 系统中有很多放置可执行文件的目录,但 /bin 比较特殊。/bin 放置的是在单用户维护模式下还能够被操作的命令。在 /bin 下面的命令可以被 root 与一般帐号使用。下面列出 /bin 下文件与目录。

可以发现常用的 cp, grep, ls, dir, more, rm, cat 等命令都在 /bin 下。

1.2 /boot 目录

放置内容: 这个目录下放置开机会使用到的文件,包括 linux 内核文件以及开机菜单与开机所配置文件等。

/grub 是一个目录,继续查看 /grub 目录内容:

还有很多以 .mod .img .o的文件,我没有全部列出来。我猜测 /grub 文件应该是 linux 开机引导程序。

1.3 /cdrom 目录是一个空目录,具体含义未知。

1.4 /dev 目录

放置内容: 在 linux 系统上,任何设备与接口都是以文件的形式存在于这个目录中。访问这些文件,就相当于访问某个设备。 查看目录内容:

硬盘,光驱,鼠标,键盘 都是以文件的方式放在这个目录下。

1.4 /etc 目录

放置内容: 系统的主要配置文件几乎都放置在这个目录下。一般来说,这个目录下的各个文件属性是可以让一般用户查阅的,但是只有 root 有权利修改。 FHS 建议不要放置可执行文件在这个目录中。 查看目录内容:

一些重要的目录有:

  • /etc/init.d/: 所有服务的默认启动脚本都是放置在这里的。
  • /etc/xinetd.d/: 这就是所谓的的 super daemon 管理的各项服务的配置文件目录。但是在我的 ubuntu /etc/ 下并无此文件。
  • /etc/X11/: 与 X Window 有关的各种配置文件都在这里。

1.5 /home 目录

放置内容: 系统默认的用户主文件夹。每创建一个一般用户帐号,默认的用户主文件夹都会规范到这里来。

1.6 /lib 目录

放置内容: 放置开机时会用到的函数库,以及在 /bin 或 /sbin 下面的命令会调用的函数。 查看目录内容:

/lib/modules/ 放置内核相关的模块(驱动程序)

1.7 /media 目录

放置内容: 放置可删除的设备。包括软盘、光盘、DVD 等设备都在暂时挂载于此。

1.8 /mnt 目录

放置内容: 挂载某些额外的设备

1.9 /opt 目录

放置内容: 第三方软件放置的目录。如果你想自行安装额外的软件(非原本的 distribution 提供的),那么也能够将你的软件安装到这里来。 在我的 ubuntu 下, /opt/ 中只有 birl 一个文件,因为我安装了一个 birl。

1.10 /root 目录

放置内容: 系统管理员(root)的主文件夹。之所以放在这里,是因为如果进入单用户维护模式而仅挂载根目录时,该文件能够拥有 root 的主文件夹,所以希望 root 的主文件夹与根目录放置在同一个分区中。 只有 root 权限才可以访问 /root 目录。

1.11 /sbin 目录

放置内容: 开机过程中所需要的,里面包括开机、修复、还原系统所需要的命令。某些服务器软件程序,一般放置到 /usr/sbin/ 当中。本机自行安装的软件所产生的系统执行文件,则放置到 /usr/local/sbin 中。 查看 /sbin 目录:

1.12 /srv 目录

放置内容: "service" 的缩写,是一些网络服务启动后,这些服务所需要取用的数据目录。常见的服务例如 WWW,FTP 等。

1.13 /tmp 目录

放置内容: 一般用户或者是正在执行的程序暂时放置文件的地方。这个目录任何人都可以访问,所以需要定期清理一下。 查看 /tmp/ 目录:

1.14 /lost+found 目录

放置内容: 放置 ext2/ext3 文件系统格式才会产生的一个目录,目的在于当文件系统发生错误时,将一些丢失的片段放置到这个目录下。这个目录通常会放置在分区的最顶层存在。 我的 ubuntu 文件格式为 ext4,/lost+found/ 目录中无内容 (不知道这样的解释对不对?)

1.15 /proc 目录

放置内容: 这个目录本身是一个虚拟文件系统(virtual filesystem)。它放置的数据都是在内存中,例如系统内核、进程、外部设备的状态及网络状态等。目录下所有数据都是在内存中,所以本身不占任何硬盘空间。 查看 /proc 目录:

比较重要的有 /proc/dma, /proc/interrupts, /proc/cpuinfo 等。

1.16 /sys 目录

放置内容: 虚拟文件系统,主要记录与内核相关的信息,包括目前已加载的内核模块与内核检测到的硬件设备信息,同样不占硬盘容量。 查看内容:

2. /usr 的意义与内容

usr: UNIX Software Resource. "Unix 操作系统软件资源" 所放置的目录,不是用户数据。 FHS 建议所有的软件开发者应该将他们的数据合理的放置到这个目录下的子目录,而不是自行新建该软件自己独立的目录。 查看 /usr 目录结构:

2.1 /usr/bin 目录

放置内容: 绝大部分的用户可使用命令都放在这里。和 /bin 的不同之处在于是否与开机过程有关。

2.2 /usr/include 目录

放置内容: C/C++ 等程序设计语言(header)与包含文件(include) 放置处,当我们以 tarball 方式安装某些数据时,会使用到里头的许多包含文件。 查看内容:

看到这,很多做 C/C++ 开发的程序员会不会有种豁然开朗的感觉呢,至少我是这样。

2.3 /usr/local 目录

放置内容: 系统管理员在本机自行安装自己下载的软件,建议安装到此目录,这样方便管理。/local 中也包括 bin, etc, include, lib 等子目录

2.4 /usr/sbin 目录

放置内容: 非系统正常运行所需要的系统命令。最常见的就是某些网络服务器软件的服务命令(daemon)。

2.5 /usr/share 目录

放置内容: 共享文件,在这个目录下放置的数据几乎是不分硬件架构均可读的数据。

举两个例子:

  1. /usr/share/emacs/site-lisp 是 emacs 加载目录。
  2. 如何你的系统是双系统,假如要修改默认启动项,只需修改 /usr/share/grub/default/grub 文件。

2.6 /usr/src 目录

放置内容: src for source ,一般源码放置到这里。内核源码一般放置到 /usr/src/linux/ 目录下。 查看内容:

想必不同的 linux-header-* 是由于我升级系统造成的。

3 /var 的意义和内容

如果 /usr 是安装时会占用较大硬盘容量的目录,那么 /var 就是在系统后才会渐渐占用硬盘容量的目录。因为 /var 主要针对常态性变动的文件,包括缓存,登录文件以及软件运行所产生的文件。 查看目录:

3.1 /var/cache 目录

放置内容: 应用程序本身运行过程中会产生的一些暂存文件。

3.2 /var/local 目录

放置内容: 程序本身执行过程中,需要使用的数据库文件放置的目录。

3.3 /var/lock 目录

放置内容: 某些设备或者是文件资源一次只能被一个应用程序所使用,如果同时有两个程序使用该设备时,就可能产生一些错误的状况,因此就要将该设备上锁(lock),以确保该设备只会给单一软件所使用。

3.4 /var/log 目录

放置内容: 登录文件。

3.5 /var/mail 目录

放置内容: 个人电子邮件信箱的目录,不过这个目录也被放置到 /var/spool/mail/ 目录中。通常这两个文件的互为链接文件

3.6 /var/run 目录

放置内容: 某些程序或者服务启动后,会将他们的 PID 放置在这个目录下。

3.7 /var/spool 目录

放置内容: 一些队列数据,这些数据使用后一般会被删除。

4 /selinux 的意义和内容

同样放置内存中的信息,不占用任何硬盘容量。/selinux 是 Secure Enhance Linux 的执行目录,而 SELinux 是 Linux 内核的重要外挂功能之一,它可以作为具体权限的管理,主要针对程序(尤其是网络程序)的访问权限。


Linux文件管理从用户的层面介绍了Linux管理文件的方式。Linux有一个树状结构来组织文件。树的顶端为根目录(/),节点为目录,而末端的叶子为包含数据的文件。当我们给出一个文件的完整路径时,我们从根目录出发,经过沿途各个目录,最终到达文件。

我们可以对文件进行许多操作,比如打开和读写。在Linux文件管理相关命令中,我们看到许多对文件进行操作的命令。它们大都基于对文件的打开和读写操作。比如cat可以打开文件,读取数据,最后在终端显示:

$cat test.txt

 

对于Linux下的程序员来说,了解文件系统的底层组织方式,是深入进行系统编程所必备的。即使是普通的Linux用户,也可以根据相关的内容,设计出更好的系统维护方案。

 

存储设备分区

文件系统的最终目的是把大量数据有组织的放入持久性(persistant)的存储设备中,比如硬盘和磁盘。这些存储设备与内存不同。它们的存储能力具有持久性,不会因为断电而消失;存储量大,但读取速度慢。

 

观察常见存储设备。最开始的区域是MBR,用于Linux开机启动(参考Linux开机启动)。剩余的空间可能分成数个分区(partition)。每个分区有一个相关的分区表(Partition table),记录分区的相关信息。这个分区表是储存在分区之外的。分区表说明了对应分区的起始位置和分区的大小。

 

我们在Windows系统常常看到C分区、D分区等。Linux系统下也可以有多个分区,但都被挂载在同一个文件系统树上。

数据被存入到某个分区中。一个典型的Linux分区(partition)包含有下面各个部分:

 

分区的第一个部分是启动区(Boot block),它主要是为计算机开机服务的。Linux开机启动后,会首先载入MBR,随后MBR从某个硬盘的启动区加载程序。该程序负责进一步的操作系统的加载和启动。为了方便管理,即使某个分区中没有安装操作系统,Linux也会在该分区预留启动区。

启动区之后的是超级区(Super block)。它存储有文件系统的相关信息,包括文件系统的类型,inode的数目,数据块的数目。

随后是多个inodes,它们是实现文件存储的关键。在Linux系统中,一个文件可以分成几个数据块存储,就好像是分散在各地的龙珠一样。为了顺利的收集齐龙珠,我们需要一个“雷达”的指引:该文件对应的inode。每个文件对应一个inode。这个inode中包含多个指针,指向属于该文件各个数据块。当操作系统需要读取文件时,只需要对应inode的"地图",收集起分散的数据块,就可以收获我们的文件了。

 

 

最后一部分,就是真正储存数据的数据块们(data blocks)了。

 

inode简介

上面我们看到了存储设备的宏观结构。我们要深入到分区的结构,特别是文件在分区中的存储方式。

文件是文件系统对数据的分割单元。文件系统用目录来组织文件,赋予文件以上下分级的结构。在硬盘上实现这一分级结构的关键,是使用inode来虚拟普通文件和目录文件对象。

 

Linux文件管理中,我们知道,一个文件除了自身的数据之外,还有一个附属信息,即文件的元数据(metadata)。这个元数据用于记录文件的许多信息,比如文件大小,拥有人,所属的组,修改日期等等。元数据并不包含在文件的数据中,而是由操作系统维护的。事实上,这个所谓的元数据就包含在inode中。我们可以用$ls -l filename来查看这些元数据。正如我们上面看到的,inode所占据的区域与数据块的区域不同。每个inode有一个唯一的整数编号(inode number)表示。

 

在保存元数据,inode是“文件”从抽象到具体的关键。正如上一节中提到的,inode储存由一些指针,这些指针指向存储设备中的一些数据块,文件的内容就储存在这些数据块中。当Linux想要打开一个文件时,只需要找到文件对应的inode,然后沿着指针,将所有的数据块收集起来,就可以在内存中组成一个文件的数据了。

 数据块在1, 32, 0, ...

inode并不是组织文件的唯一方式。最简单的组织文件的方法,是把文件依次顺序的放入存储设备,DVD就采取了类似的方式。但如果有删除操作,删除造成的空余空间夹杂在正常文件之间,很难利用和管理。

复杂的方式可以使用链表,每个数据块都有一个指针,指向属于同一文件的下一个数据块。这样的好处是可以利用零散的空余空间,坏处是对文件的操作必须按照线性方式进行。如果想随机存取,那么必须遍历链表,直到目标位置。由于这一遍历不是在内存进行,所以速度很慢。

FAT系统是将上面链表的指针取出,放入到内存的一个数组中。这样,FAT可以根据内存的索引,迅速的找到一个文件。这样做的主要问题是,索引数组的大小与数据块的总数相同。因此,存储设备很大的话,这个索引数组会比较大。

inode既可以充分利用空间,在内存占据空间不与存储设备相关,解决了上面的问题。但inode也有自己的问题。每个inode能够存储的数据块指针总数是固定的。如果一个文件需要的数据块超过这一总数,inode需要额外的空间来存储多出来的指针。

 

inode示例 

在Linux中,我们通过解析路径,根据沿途的目录文件来找到某个文件。目录中的条目除了所包含的文件名,还有对应的inode编号。当我们输入$cat /var/test.txt时,Linux将在根目录文件中找到var这个目录文件的inode编号,然后根据inode合成var的数据。随后,根据var中的记录,找到text.txt的inode编号,沿着inode中的指针,收集数据块,合成text.txt的数据。整个过程中,我们参考了三个inode:根目录文件,var目录文件,text.txt文件的inodes。

在Linux下,可以使用$stat filename,来查询某个文件对应的inode编号。

 

在存储设备中实际上存储为:

 

当我们读取一个文件时,实际上是在目录中找到了这个文件的inode编号,然后根据inode的指针,把数据块组合起来,放入内存供进一步的处理。当我们写入一个文件时,是分配一个空白inode给该文件,将其inode编号记入该文件所属的目录,然后选取空白的数据块,让inode的指针指像这些数据块,并放入内存中的数据。

 

文件共享

在Linux的进程中,当我们打开一个文件时,返回的是一个文件描述符。这个文件描述符是一个数组的下标,对应数组元素为一个指针。有趣的是,这个指针并没有直接指向文件的inode,而是指向了一个文件表格,再通过该表格,指向加载到内存中的目标文件的inode。如下图,一个进程打开了两个文件。

可以看到,每个文件表格中记录了文件打开的状态(status flags),比如只读,写入等,还记录了每个文件的当前读写位置(offset)。当有两个进程打开同一个文件时,可以有两个文件表格,每个文件表格对应的打开状态和当前位置不同,从而支持一些文件共享的操作,比如同时读取。

要注意的是进程fork之后的情况,子进程将只复制文件描述符的数组,而和父进程共享内核维护的文件表格和inode。此时要特别小心程序的编写。






原文地址:http://www.perfect-is-shit.com/linux-context-meanning.html



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值