本节书摘来自华章计算机《Linux嵌入式实时应用开发实战(原书第3版)》一书中的第3章,第3.5节,作者:(美)Doug Abbott 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
3.5 Linux文件系统
Linux文件系统在很多方面与Windows PC或Macintosh(苹果公司生产的)上的文件系统类似。它是一个等级系统,允许你在“/”标识的根目录下创建任何数量的子目录。和Windows中一样,文件名可以很长。尽管如此,Linux和多数类似UNIX的系统一样,文件的扩展名——文件名中“.”后面的那部分——不像它们在Windows中那样有意义。例如,Windows中的可执行文件的扩展名为“.exe”,但是Linux中的可执行文件根本没有扩展名。大体上,一个文件的内容是通过文件头而不是特定的扩展名来识别的。尽管如此,一些应用,例如C编译器,也支持默认的文件扩展名。
和Windows中不同,Linux中的文件名是区分大小写的。Foobar、foobar、fooBar均是不同的文件,排序也是区分大小写的。在按名称排序的目录列表中,以大写字母开头的文件名会排在那些以小写字母开头的文件名之前。以“.”开始的文件名是隐藏的,将不会显示在目录列表中,除非你特别指出要列出它们。
另外,Linux文件系统还有很多在典型的Windows系统中找不到的属性。接下来我们看一些嵌入式程序员可能感兴趣的属性。
3.5.1 文件权限
因为Linux是多用户,每个文件都有一组与之关联的权限指定什么级别的用户可以操作该文件。在shell命令窗口输入命令ls-l或使用一个桌面文件管理器来看一些Linux目录的细节列表。每个文件的部分入口都是一组10个标志位和一对名字,比如像下面这样:
-rw-r–r– Andy physics
在这个例子里,Andy是文件的拥有者,文件属于一组叫做physics的用户,或许是一些大学里的物理系。通常,拥有者就是创建该文件的人,但也并不总是这样。
10个标志中的第一个标识了文件类型。普通的文件这里会有一个短划线。目录以“d”标识,链接是“l”等。在后面涉及设备驱动时,我们将可以看到该标志的其他入口。剩下的9个标志,分成3组,每组3个标志。每组的标志都是相同的,分别代表允许读文件(“r”),允许写文件(“w”),或执行文件(如果是可执行文件的话)(“x”)。写权限也允许删除文件。
三组代表对不同级别用户的授权。第一组标识给文件拥有者的授权,几乎总是允许读和写。第二组标志授权给同一组用户内的其他成员,在这里physics组内的成员可以读文件,但是不能写。最后一组授权给“全世界”,即所有用户。
这里我们再看一下“x”许可。在Windows里,认为有.exe扩展名的文件是可执行文件。在Linux里,因为我们没有明显的文件扩展名,因此就用“x”许可识别一个二进制可执行文件。另外,只有设置了有“x”授权等级的用户才可以调用文件的执行。所以如果以一个普通用户的身份登录,将不能调用那些可能改变整个系统状态的程序,如改变网络地址。
另一个“x”的有趣的属性也适用于shell 脚本,我们将在本章的后面讨论这些内容。对于喜欢DOS的你,shell脚本就和.bat文件一样。它是一个可以当作程序执行的命令的文本文件。但是shell不会执行脚本,除非它设置了“x”位。
3.5.2 “根”用户
在每个Linux系统中,都有一个很特别的用户叫“根”。无论许可标志位是什么,根都可以对任何文件进行任何操作。根最初是为系统管理的目的设置的,不推荐日常使用。显然,如果你不小心,可能引起很多问题,而且根的特权有一个潜在的安全威胁。尽管如此,嵌入式和实时开发者对系统进行的操作经常需要写或执行由根拥有的文件,因此要求以根用户登录。
过去,多数时间我会作为根用户登录,因为麻烦比较少。这样做的后果是我创建的每个文件都是根所拥有,如果不改变权限就不能被普通用户写。这成了一个恶性循环。我作为根用户登录的越多,我就不得不更多地以根用户登录来做任何有用的事。我已经开始采用更谨慎的方法以普通用户登录了,只是在必要时才切换到根用户。
如果你以一个普通用户登录,你可以通过替代用户su(substitude user)或sudo命令切换到根用户。只要你输入正确的根口令,没有参量的su命令就会启动一个有根特权的shell。如果要返回普通用户状态,通过输入^d或exit终止shell即可。
只要你在/etc/sudoers 下的sudoers文件里有合法的授权,sudo命令就允许你以根用户执行一个命令。sudoers文件当然是根拥有的,所以只有根用户可以授权sudoers。一旦你有了授权,就可以通过输入你的口令,在短时间内(默认是5分钟)使用sudo而不需要再输入你的口令。
例如,如果我想改变/dev目录下一个文件的权限,可以执行:
sudo chmod o +rw/dev/ttyS0
会有提示要我输入口令,如果输入正确,命令就可以执行。然后我可以继续执行5分钟的sudo命令而无需再重新输入口令。注意sudo比su提供更好的安全性,因为根用户必须授权sudoers,而根口令肯定是保密的。
3.5.3 /proc文件系统
/proc文件系统是Linux的一个有趣特性。它和普通的文件系统一样工作。你可以列出/proc目录下的文件,你可以读写文件,但是它们并不存在。当读文件时,会动态生成/proc文件的信息。内核模块注册了一个给定的/proc文件,包含产生读数据和接受写数据的函数。
/proc文件是一个通往内核的窗口。它以用户级任务和shell易于获取的方式提供关于系统状态的动态信息。在图3-8列出的简短目录里,有数字标签的目录代表进程。每个进程在/proc下都有一个目录,并有几个目录和文件描述进程的状态。
试一试
看一下Linux通过开机启动多少进程是非常有意思的。重启你的系统,打开一个命令shell,执行:
ps –A|wc
ps命令列出了系统中正在运行的进程。ps的输出是每个进程一行。wc命令是计算行数、字数、传递给它的字符数。行数本质上就是正在运行的进程数。在我的Fedora14系统中,有281个进程在运行。
现在试一下:
ps –A|more
这个命令是给你看ps的输出,一次一页。注意,ps命令的信息来自/proc文件系统。
另一个命令突出了/proc数据的实时属性。执行:
cat/proc/interrupts
interrupts文件列出了系统中的所有中断源,从系统启动开始,每个中断的发生次数和驱动对中断的注册情况。现在,再次执行命令:
cat/proc/interrupts
你将看到一些数字有了增长,因此证明了该数据是动态生成的。
3.5.4 文件系统等级标准
一个Linux系统通常包含很多文件,例如,一个典型的Fedora安装可能包括约30 000个文件,需要几个GB的磁盘空间。很显然,需要将这些文件通过统一的规则组织起来。这就是创建文件系统等级标准(FHS)的原因。该标准允许用户和软件开发者预测安装文件和目录的位置。FHS绝不是Linux特有的,它通常也应用于类UNIX的操作系统。
Linux文件系统的目录结构总是从根开始,以“/”标识。FHS指定了根目录下的几个目录和它们的内容,如图3-9所描述的。FHS从两个独立的方面描述文件:
- 共享与独占。一个网络系统可以通过网络文件系统(NFS)挂接一些目录以使多个用户可以共享可执行文件。但是,一些信息仍然是属于特定计算机而不能被共享的。
- 静态与可变。Linux系统中的一些文件是可执行,不能改变的,它们是静态的。但是用户创建或通过下载或邮件得到的文件是可变的。这两种不同的文件需要区分清楚。
https://yqfile.alicdn.com/8c2b8186cc75b5868d3680c03f7b4b6f4240e398.png" >
以下是FHS定义的目录的描述:
- /bin:包括用户和系统管理员使用的命令的二进制可执行文件。FHS指定了/bin必须包含的文件,其中包括shell命令和基本的文件实用程序等。/bin文件是静态的和共享的。
- /boot:除配置文件和映射安装外,包含了启动进程需要的所有文件。除了内核可执行镜像,/boot还包括内核在执行用户模式程序前使用的数据。/boot文件是静态和非共享的。
- /etc:包括主机指定的配置文件和目录。除了包含文件系统动态信息的mtab外,/etc的其他文件都是静态的。FHS可识别三个可选的/etc子目录:
- /opt:包含附加应用包的配置文件。
- /sgml:标准通用标识语言(SGML)和扩展标识语言(XML)的配置文件。
- /xll:X窗口的配置文件。
实际中,多数的Linux发行版都有更多的/etc的子目录,代表可选的启动和配置需求。 - /home:(可选的)包括用户本地目录。每个用户都在home下有一个子目录,目录名和他/她的用户名相同。尽管FHS将这项设为可选,事实上,它在UNIX系统中几乎是通用的做法。在/home下子目录内的内容当然是可变的。
- /lib:包含在根文件系统里启动系统和运行命令需要的共享库镜像,如在/bin和/sbin下的二进制文件。在Linux系统里,/lib有一个子目录/modules,包含内核可载入模块。
- /media:可移动媒体的挂载点。当一个可移动媒介是自动挂载时,挂载点通常就是卷名。
- /mnt:提供一个方便的位置以临时挂载一个文件系统。
- /opt:包括可选的附加软件包,每个包在/opt下都有自己的子目录。
- /root:根用户的本地目录。这不是FHS要求的,但是实际中的通用做法,也是高度推荐使用的。
- /sbin:包括系统管理必要的二进制实用文件,如在启动、恢复、重建或修复系统时使用的。这些实用程序通常只能是系统管理员使用。普通用户在他们的路径里不需要/sbin。
- /tmp:临时文件。
- /usr:第二等级。在后面详述。
- /var:可变数据。包括工作目录和文件、管理和登录数据、瞬态和临时文件。基本上,包括操作时所有系统数据的改变。在/var下有很多子目录。
/usr等级
/usr是第二等级,包括面向用户的文件。图3-10显示了在/usr下的子目录。其中的几个在根目录下映射了功能。也许,/usr里最有意思的子目录是关于源代码的/src。这通常是Linux源代码安装的地方。你可以在/src下安装几种不同的Linux内核源代码,子目录的名称如下:
linux-<version number>-ext
这样你就可以有一个名叫Linux的逻辑链接指向你当前正在使用的内核版本。
3.5.5 挂载文件系统
Windows和Linux文件系统的一个主要的不同之处在于文件结构的设备、硬盘、软驱、CD-ROM等如何映射到系统的目录或等级结构中。Windows文件系统使设备明确可见,用字母和冒号的组合来表示,如“C:”。但Linux强调一个统一的文件系统,其中物理设备是不可见的。
将物理设备映射到文件系统目录结构的机制叫做挂载(mounting)。可移动的媒体设备如CD-ROM驱动是该特征的最显著的表现。在你读CD-ROM前,你必须使用如下的mount命令将该驱动挂载到目录结构中存在的一个节点上:
mount/media/cdrom
该命令有效的原因是文件/etc/fstab包含/media/cdrom上通常挂载的设备是什么和设备包含的文件系统类型(在这里是iso9660)的信息。
像文件许可一样,如果你要做的只是从一个CD上读几个文件时,挂载可能很麻烦。但是挂载范例的真正价值在于它不局限于直接连接到计算机上的物理设备,也不仅仅识别自己的Linux文件系统。在后面我们将看到,我们可以将部分文件系统挂载到连接到网络的远程计算机上,以便本地计算机可以访问它们的文件。也可以将包含DOS FAT或VFAT的文件系统的设备进行挂载。如果你建立了一个可以启动Windows或Linux的双启动系统,那么这个属性可能是特别有用的。这样的两个系统之间的文件易于共享。