【资料】Linux基础教程 第2章 Linux基础
第2章 Linux基础
本章要点:
本章介绍Linux的一些基本概念,特别是文件系统和进程管理的基本知识。
本章具体包括以下内容。
LINUX文件系统概述
系统内核概述
shell脚本的基本格式
UNIX的用户权限和用户账号管理
进程管理的基本概念和操作
Linux的发行版本
2.1 文件系统
让我们首先来解释Linux的文件系统概念。我无意将你培养成为职业的系统破坏者,只
是介绍一些基本概念。特别地,直接操作设备的物理扇区来读写ext2文件系统这样的想
法让我只要想一下就会脖子发凉,如果你是这方面的专家,请告诉我到底怎么做。
2.1.1 UNIX和树状文件系统
与普通的UNIX系统一样,Linux使用树状的文件系统。每个系统都有一个根目录,从这
里开始可以遍历整个系统中的所有文件,它没有驱动器和盘符的概念。
你可能会怀疑在没有驱动器符的情况下Linux如何处理多于一个的磁盘分区,可以看一
下下面的示意图:
图2.1 文件系统示例
在我们的例子里,在/下有四个目录,其中,/bin直接和/位于同一个分区中,这个包
含/的分区称为根分区。除此之外,根分区下还存在三个目录:/home,/mnt和/usr。
在系统中要存放大量的常用文件,例如日常的命令,系统文档等等。我们分划了一个
独立的分区用来存放这些文件,这个分区被“连接”在/usr目录下,因此要访问分区上
的文件只要访问/usr目录就可以了。
同样,我们为用户的私人文件开设了一个分区,连接在/home下面,每个用户都可以使
用自己的目录内的文件(比如:/home/emp1)。但是我们发现有一个目录需要容纳特别
多的文件,以至于将它单独分区可能会好一些,因此我们又设置了一个独立的磁盘用来
容纳这些数据,这个磁盘分区被连接到/home/httpd。
这台机器上还包含了一个DOS分区,一个光盘驱动器,另外网络中还有一个服务器提供
了共享的网络目录,我们把它们全都连接到文件系统之中,不过由于每个目录分支点(
术语叫mount point)只能安装一个文件系统,所以我们在/mnt下面开设了三个目录来连
接它们。
所有的文件都可以通过目录名加文件名来访问,对于系统来说,具体的每个文件到底
在那个磁盘或者那个服务器上是无关紧要的,只要了解这个文件所在的目录就行了。Li
nux利用/作为根目录的标志以及目录层之间的分割符,其作用相当于DOS的\。不过与DO
S不同的是,Linux的文件名、目录名命名规则要宽泛的多,可以用相当长的文件名和目
录名,在文件名和目录名中都可以包含不止一个的句点,而且区分大小写。例如 \test
和\TEST是不同的两个文件。而一个位于/mnt/dos目录下的名为file1的文件其绝对路径
名就是/mnt/dos/file1。
应该指出的是,“文件系统”这个词在Linux文献中有几种含义,第一种用来描述我们
这里说的从/开始的系统中所有文件和目录的集合;第二种用来描述如同我们例子里面与
/usr对应的那个分区那样的可以直接连接到某个目录下的完整集合体,即文件系统的一
个独立部分;第三种含义是文件系统的具体实现方式,即操作系统如何把这种逻辑的目
录结构映射成磁盘上的数据。具体的含义很容易根据上下文判断出来,大家可以自己注
意。
用cd命令可以在不同的目录之间切换,Linux承认绝对路径和相对路径,这个内容对于
任何熟悉dos的用户都应该是极其简单的,例如从/mnt/dos切换当前路径到/home/httpd
的命令可以是cd /home/httpd,也可以是cd ../../home/httpd。但是必须注意的是,在
cd命令之后的空格不可省略。
尽管理论上Linux应该自动对文件名进行过滤,但是这方面仍然有一些问题,例如,L
inux允许用减号作为一个文件的起始字母,然而-也用于许多命令后的开关,因此会带来
一些问题,如果你碰到了类似的问题,有时候使用绝对路径名会解决问题。
2.1.2 文件类型和文件组织
Linux把许多不同的东西看成文件。在一般情况下,我们会碰到下面类型的文件:
普通文件
目录
设备文件
链接
普通文件和目录
普通文件和目录的含义与DOS或者windows下的概念是类似的,普通文件就是一些数据
的集合,而目录则是包含文件的容器。实际上,目录也是一种特殊的文件,只是它包含
的内容是文件的存放信息。文件可以用rm命令删除,目录用mkdir命令建立,用rmdir删
除。
设备文件
UNIX设备被当成文件来处理,通常UNIX的设备文件被分成字符设备和块设备,字符设
备通常是类似于终端那样可以用处理文本文件的方式来处理的东西,例如,Linux在启动
时打开了六个虚拟终端,分别称为tty1到tty6,这些虚拟终端对应的文件是/dev/tty1到
/dev/tty6。假设你有超级用户权限,就可以直接向这些TTY上写文本,而这些文本则会
显示在主机的控制台上。块设备则代表了类似磁盘的东西,如磁盘,CD-ROM或者虚拟驱
动器。一般情况下,每个块设备还要包含一些子设备,例如,第一个IDE硬盘被称为hda
,但是这个硬盘可以包含多个分区,那么,第一个分区称为hda1,以下依次是hda2,hda
3,….等等。
设备文件用mknod命令建立,用rm命令删除。
链接
链接实际是一种文件别名,每个文件至少应该有一个名字,而如果你需要给文件增加
一个名字以便访问,那么就需要建立一个链接。链接被分为软链接和硬链接。软链接实
际上只是一段文字,里面包含着它所指向的文件的名字,系统看到软链接后自动跳到对
应的文件位置处进行处理;相反,硬联接为文件开设一个新的目录项,硬链接与文件原
有的名字是平权的,在Linux看来它们是等价的。由于这个原因,硬链接不能连接两个不
同文件系统上的文件。
链接可以用ln命令创建,例如,在/home/user目录下有一个文件dest,现在需要在/
tmp目录下建立一个链接以便直接在/tmp下访问它,那么可以用这样的命令:
ln /home/user/dest /tmp/dest
这个操作将会建立一个硬链接,但如果/home/user和/tmp在不同分区上时这个命令将
会失败。
ln –s /home/user /tmp/dest
这个命令将建立一个软链接。
如同其它UNIX Like系统一样,Linux的目录组织经常给人晕头转向的感觉,下面是一
些基本的目录的说明。注意,理论上你可以更改这些目录的位置和名字,但是这样做很
可能使一些假定文件“就在哪里”的程序混乱。
/:所有目录的“祖先”。
/lib:大部分应用程序必须使用的动态连结库文件
/usr:绝大部分的东西都在那里,比较复杂的应用程序(/usr/bin,/usr/sbin),
应用程序的附加文件(/usr/lib),应用程序的文档(/usr/doc),应用程序的联机手册
(/usr/man)。
/usr/local:这里是一般的附加软件的安装地点,如果你在安装了Linux之后又试图安
装新的应用程序包,通常会被安装在这里。
/var:这里包含的是一些随着系统运行会不断改变的内容,例如各种记账信息,邮件
和打印队列等等。许多人建议把它单独构成一个分区。
/tmp:临时文件,有必要的话将它独立成一个分区。
/dev:Linux用这个目录存放设备文件。
/proc:这实际上不是一个磁盘目录,而是用来显示系统的运行状态,在其中包含各
种虚拟“文件”用来显示系统的当前状况,如进程和CPU等等。
/mnt:习惯上在这个目录下开设出各种文件系统的连结点,但你可以随便更改它而不
会带来任何问题。
/home:缺省的非超级用户的宿主目录的所在地点。
2.1.3 使用文件系统
通常,对于服务器,我们在安装的同时就为它设计好了文件系统,特别是如何分区,
某个分区应该连结到哪个目录下等等。但是我们也需要对文件系统进行维护,例如为服
务器增加一个硬盘,或者解决文件系统混乱的灾难性问题等等。另外,诸如CD-ROM,软
磁盘,或者服务器上的共享目录等等显然是需要经常更换的,在Linux中,用文件系统的
安装和拆卸来对付这样的问题。
本节不会涉及那些有关处理文件系统灾难或者建立新的分区之类的问题;这种问题可
以参考系统配置和日常维护的那两章,这里只是介绍一些基本的知识。
一个文件系统可以连结到已有的Linux系统中,也可以把连结上的文件系统从整个目录
树中脱离,这是用mount和umount命令实现的。
mount命令的格式是
mount 开关 分区或者设备名 文件系统连结点
开关是一些命令参数,例如,假定我们需要使用某个软盘上的文件,将它插入驱动器
A,然后执行
mount /dev/fd0 /mnt/floppy
然后软盘的文件系统就被挂到/mnt/floppy目录下,相当于dos的a:\file1的文件现在
的名字是/mnt/floppy/file1。注意mount命令要求在挂接之前连结点(在这个例子中是/
mnt/floppy)必须存在,否则无法执行。
一般总是把文件系统连结到某个空目录。假如/mnt/floppy目录在连结之前就包含某些
文件,那么执行上述命令的结果将使/mnt/floppy目录的内容变为软磁盘上的内容,而原
有的内容在卸掉这个文件系统之前将不可访问。
/dev/fd0是与驱动器A对应的设备,相应地驱动器B是/dev/fd1。硬盘的情况比较复杂
,因为Linux是利用设备接口来描述设备的,例如,第一个IDE接口上的主盘是/dev/hda
,从盘是/dev/hdb,第二个IDE接口上的两个盘是/dev/hdc和/dev/hdd。问题是由于硬盘
使用的是分区,所以必须使用子设备名,例如,把/dev/hda上的第一个分区连结到/mnt
/diskc上的命令是
mount /dev/hda1 /mnt/diskc
相应地,第二个分区是/dev/hda2,以此类推
同样,SCSI驱动器用/dev/sda,/dev/sdb等等描述,对应的子设备名字是/dev/sda1,
/dev/sda2等等。
Linux对IDE光驱用硬盘的命名方式,不过光盘不存在分区问题,所以可以直接使用设
备名,例如把第二IDE从盘上的CDROM连结到/mnt/cdrom的命令是
mount /dev/hdd /mnt/cdrom
mount命令最常用的两个命令开关是-t和-o ,-t命令用来标志准备挂接的文件系统的
类型,(在下一小节中详细介绍),-o选项用来设置一些选项,最主要的选项是ro和rw
。这两个选项定义了对文件系统的存取方式,如果使用ro选项,那么这个文件系统将以
只读方式连入,无法修改上面的任何信息。缺省的设置是rw。
连结了一个文件系统之后,就可以向这个系统对应的目录进行操作,效果就是操作对
应的文件系统,如果要把这个文件系统卸下,使用umount命令,其格式是:
umount 连结点
例如,在上面的例子中,把连结在/mnt/floppy的软盘文件系统卸下的命令是
umount /mnt/floppy
注意由于这个过程会改变目录结构,因此必须在没有任何进程访问/mnt/floppy下的文
件,也没有任何用户的当前目录是/mnt/floppy或者它的下级目录时才能完成,否则会返
回一个 device is busy的错误。在有些UNIX系统中你可以用umount –f 的方法来强行
越过这个限制,但这是一种极其粗野的方式,只有你明确地知道你到底在干什么才可以
,在Linux中这个功能已经被取消。(有一个有趣的问题,如果你的文件系统是级联的,那
么在拆卸下级文件系统之前上一层文件系统不能被拆卸)由于这个原因,在有人使用系统
的情况下拆卸服务器的文件系统几乎是不可能的。如果你实在要这样干,请参考系统配
置那一章,将系统切换到单用户模式,这个过程会把所有用户从系统上踢掉,然后再完
成你的拆卸过程。
作为一种保护机制,已经mount的cd-rom不能通过按下面板上的按钮直接弹出,而必须
首先执行umount命令,当然也可以用eject命令完成umount和弹出的自动操作。对于软盘
没有这样的保护,所以你必须注意不要弹出一个已经连结的软盘,如果你这么做了,由
于unix的文件工作方式,除非这个软盘是以read only方式连入,否则几乎肯定会出现问
题。
mount和umount都需要超级用户权限才能执行,另外,它们都支持-a选项,mount –a
挂接在/etc/fstab中定义的所有可挂接文件系统;umount –a卸下所有定义在/etc/mta
b中得已挂接文件系统。每当挂接一个文件系统时,系统自动在/etc/mtab中增加一条纪
录;当这个系统被卸下时自动把纪录清除。直接输入不带参数的mount指令将会显示当前
已挂接的文件系统。
2.1.4 VFS、缓冲和ext2
每一种UNIX变体都有其独特的文件系统实现方式,Linux文件系统的实现依赖于所谓e
xt2文件系统,但是它也支持其他许多种出自其他操作系统的文件系统实现。在这个方面
,Linux引入了虚拟文件系统(VFS)的概念,任何文件系统连接入Linux时都必须先经过
VFS映射成为标准的文件系统。只要增加VFS到具体文件系统的映射,就可以让Linux支持
新的文件系统。一般说Linux必须在ext2文件系统上启动,但是也存在用基于MSDOS的某
种文件系统来实现它的可能。
VFS的最大一个影响也许是在缓冲文件方面。如同在MS-DOS上经常看到的那样,Linux
也使用内存高速缓冲磁盘的读写。事实上,为了提高性能,Linux被设计为将“几乎所有
”的空余内存都用来作为磁盘缓冲,这个设计使得Linux具有UNIX类系统中最高的磁盘效
能。(如果你对这个有兴趣,那么,有些人曾经宣布,在Linux+PeniumII+IDE上运行ta
r+zip比Sun solaris+SCSI上快一倍左右,原因是solaris不使用磁盘缓冲。)它的缓冲
对读写都同样有效,为此,系统必须每隔一段时间将缓冲区中的内容和磁盘中的内容进
行同步,如果在同步间隙中掉电,未写入的数据将会丢失。在拆卸任何文件系统或者关
机、重新启动之前,系统内核将自动同步其内容。当然你也可以使用sync命令来进行这
个同步。
尽管如此,仍然可能由于某些原因使得文件系统未能正确同步,通常造成这种现象的
原因是掉电,因此,缺省的系统启动脚本会在每次重新启动时自动检测文件系统,并且
启动fsck程序修理那些没有正确同步的文件系统。(fsck是系统管理员用来修理文件系
统的主要工具,它的用法我们将在“日常维护”中介绍。)这个命令有时要耗费很长的
时间。
Ext2是Linux的标准文件系统,与任何UNIX文件系统类似,它将磁盘分割成为一系列数
据块,再由数据块构成块组。每个文件由唯一的I节点(inode)描述,它包含文件的存放
和权限信息。象一切UNIX一样,Linux在内存中缓冲inode表来加快文件的存取。
(如果这些内容会让你糊涂,那么不要紧,你并不需要了解ext2的具体实现。实际上
对于一个非内核设计者来说理解ext2的实现的唯一理由是要去挽救一个已经被灾难完全
摧毁的文件系统。然而,备份和恢复会容易的多,不是吗?)
2.1.5 其它文件系统
Linux支持许多文件系统,“支持”的意思是说你可以把载有这些文件系统的磁盘分区
或者什么其他的设备直接连接到Linux文件系统中。一般情况下,如果要连接一个不是e
xt2的文件系统,你需要在mount命令行中用-t指令明确地给出文件系统的类型。Linux系
统目前支持的文件系统类型主要有:
minix:最早的MINIX系统的文件系统
ext2:Linux的标准文件系统,它还有一个比较早的形式即ext,目前已经不用
msdos:这就是标准的MSDOS文件系统
umsdos:这是一个特殊的文件系统实现,可以用MSDOS来存贮类似UNIX的长文件名文件
vfat:这是windows 95/98使用的文件系统,支持windows 95长文件名
iso9660:CD-ROM的标准文件系统
hpfs:OS/2用的文件系统
ntfs:windows nt 4.0用的文件系统(使用它要小心,目前这个功能还不是很可靠,
绝对不要把一个NTFS文件系统连接成rw的方式!)
ufs:BSD用的文件系统
sysv:System V系列的一些UNIX使用的文件系统。
Ext2和ISO9660通常不需要使用类型说明,而msdos/win95文件系统则常常需要明确地
说明其为msdos或者vfat,例如,在/dev/hdb2上装有一个windows 95文件系统,那么,
将它连结到/mnt/win95的命令是
mount /dev/hdb2 /mnt/win95 –t vfat
偶尔你必须为连结到文件系统中的msdos软盘说明其类型:
mount /dev/fd0 /mnt/floppy –t msdos
2.2 系统内核基础
下面我们要解释有关系统内核的一些东西。必须记住,GNU+Linux的一个特色是如此之
多的程序可以使用,因此几乎所有的东西都可以用你自己的东西替换掉,除了系统内核
。
2.2.1 什么是内核
Linux将系统的一些关键性程序分离出来构成所谓操作系统内核。象大部分UNIX操作系
统的内核那样,Linux内核必须完成下面的一些任务:
管理对文件系统的读写,把对文件系统的操作映射成对磁盘或其他块设备的操作
管理程序的运行,为程序分配资源,并且处理程序之间的通讯
管理存储器,为程序分配内存,并且管理虚拟内存
管理输入输出,将设备映射成设备文件
管理网络
文件系统的概念我们已经在前面一节中介绍过了,内核必须包含VFS管理程序以及将各
种具体文件系统映射成VFS的程序。另外的几项功能差不多也象文件系统一样复杂,首先
是对于内存的管理。
Linux使用虚拟存储管理方式,利用现代处理器的页面映射能力,在x86处理器上,Li
nux使用4GB地址空间,系统的物理存贮器通常总是少于这个数字。操作系统除了使用物
理存储器外,也支持将硬盘空间映射成为虚拟内存。所有存贮器(物理内存和虚拟内存
)分成大小相等的页面,在x86系统中,每一页的大小是4kB,通过给出页号和页面内偏
移量对某个内存地址进行访问,在物理内存紧张的时候,操作系统必须把某些没有使用
的页面从内存移动到硬盘上以便腾出空闲的页面供程序使用,这个过程称为对换。
显然对换需要虚拟存储空间,通常情况下Linux用交换分区来处理这个问题,在硬盘上
开设一个独立的分区专门用于映射虚拟内存,这种分区称为交换分区。交换分区可以并
且经常不止一个,之所以这样是由于早期的Linux核心要求每个交换分区不能超过128MB
。对于较重负荷的服务器,交换内存用到256MB甚至更多都是很正常的事情,因此那时的
系统经常有多个交换分区,目前这个限制已经去除,但仍有人使用多于一个的交换分区
。
核心的另外一个任务是执行用户程序,为此核心必须支持可执行文件格式。Linux使用
多种可执行文件的格式,诸如elf,a.out等等(与ms-dos不同,没有办法从名字上区分
一个文件到底是什么格式,核心只关心二进制文件的具体形式)。
除此之外,所有的设备驱动程序都必须包含在系统内核之中,依靠这些驱动程序操作
系统才能够对硬件进行操作。
2.2.2 可加载模块和设备驱动程序
在一些系统中内核的运行参数以及内核中包含的设备驱动程序都只能在系统启动时装
入,因此要想改变系统硬件或者对硬件的运行参数进行调整,唯一的选择是重新启动。
Linux支持在运行期间加载核心模块。
模块(modules)是Linux的概念,它意味着可以将一些功能的程序分离出来,动态地加
入和撤出内核。通常这种实现的目的是减少内核需要的物理存储空间(内核不能对换,
也不使用虚拟内存映射)以及使系统的配置更灵活。尽管理论上随意加入和拆卸内核的
功能容易使内核陷入危险中,但是Linux的实现使得加载一个内核模块实际是相当安全的
。
必须注意的是,一个放在模块中的程序和直接放在内核映像文件(例如,在许多系统
上的/vmlinuz)中的并没有什么不同,把某个部分当成模块还是直接放入内核映像的理
由通常只是为了方便。例如,尽管可以把软驱的驱动程序作成可加载模块,但是对于一
个经常使用软盘的用户来说这只会带来烦恼,因为在使用软盘之前他必须将驱动模块调
入,相反,对于一个普通用户,ntfs驱动程序可以合情合理地做成模块,因为需要访问
windows NT分区的几率肯定是很小的。网卡和声卡驱动程序也通常做成模块的形式,因
为它们的种类实在太多,在内核中包含所有的驱动程序肯定是一种疯狂的想法。
内核模块可以用insmod命令加载,用rmmod命令卸载,其语法是:
/sbin/insmod 模块名
/sbin/rmmod 模块名
而使用lsmod命令可以显示当前加入的内核模块。
由于许多模块的加载都涉及到复杂的版本、相互依赖等问题,所以Linux文档提倡使用
更简单的modprobe命令来加载模块:
/sbin/modprobe 模块名
需要指出的是,模块是在编译系统内核时设定的,通常在/lib/modules目录下有一个
目录,其名字是你的内核版本号(比如:2.2,14),而各种模块都包含在这个目录下,
名字是xxxx.o,xxxx是模块名,而.o是缺省的扩展名。在使用上面的各个命令时,不需
要使用扩展名也不需要使用路径。例如,使用/lib/modules/2.2.14/ipv4/ip_masq_qua
ke.o的命令为
/sbin/modprobe ip_masq_quake.o
也存在另外一种方案,这种方式中,当核心需要某个模块时,它自动去寻找对应的模
块文件并且将它加载到系统中。这是通过正确地编译内核实现的,不过,一般不推荐使
用这样的办法,因为增大了出现意外事故的几率。
2.2.3 内核不做什么
Linux内核是一个比较复杂的程序,技术上讲,它不同于一些现代操作系统所采用的微
内核,相反,许许多多的东西被加入到了内核之中。但是,比起许多其他系统,Linux内
核是非常小而且简单的。另外,许多东西虽然是Linux的一部分但是和内核完全无关,拆
卸它们至少在理论上不会影响系统的正常运转。
首先的可以拆卸或者替换的东西是命令解释程序,再就是X-Window,这些东西只是几
个应用程序,它们并不运行在核心态中,对于Linux它们也不是绝对必要的(然而,这种
说法也许只有理论上的意义,一个没有shell的Linux几乎肯定是不可操作的)。
2.3 shell和配置程序
作为一个UNIX系统管理者,你必须了解shell。Linux在对shell的依赖方面比其它UNI
X产品好一些,因为有近乎无穷多的shell和相关的自动化工具可用。不过,我想无论如
何,你都必须了解bash,这是Linux的缺省shell。