第2部分 从系统管理角度学习Linux命令
第2章 Linux文件系统及其相关处理命令
2.1 Linux的文件系统介绍
2.1.1 文件系统定义
首先回答最常见的问题,“什么是文件系统”。文件系统是对一个存储设备上的数据和元数据进行组织的机制。由于定义如此宽泛,支持它的代码会很有意思。正如前面提到的,有许多种文件系统和媒体。由于存在这么多类型,可以预料到Linux文件系统接口实现为分层的体系结构,从而将用户接口层、文件系统实现和操作存储设备的驱动程序分隔开。
另一种看待文件系统的方式是把它看做一个协议。网络协议(比如IP)规定了互联网上传输的数据流的意义,同样,文件系统会给出特定存储媒体上数据的意义。
2.1.2 Linux文件系统的体系结构
大多数文件系统代码在内核中(用户空间文件系统除外),但是如图2-1所示的体系结构显示了用户空间和内核中与文件系统相关的主要组件之间的关系。
图2-1 用户空间和内核中与文件系统相关的主要组件之间的关系
用户空间包含一些应用程序(例如,文件系统的使用者)和GNU C库(glibc),它们为文件系统调用(打开、读取、写和关闭)提供用户接口。系统调用接口的作用就像是交换器,它将系统调用从用户空间发送到内核空间中的适当端点。
VFS是底层文件系统的主要接口。这个组件导出一组接口,然后将它们抽象到各个文件系统,各个文件系统的行为可能差异很大。有两个针对文件系统对象的缓存(inode和dentry)。它们缓存最近使用过的文件系统对象。每个个体文件系统实现(比如ext2、JFS等)导出一组通用接口,供VFS使用。缓冲区缓存会缓存文件系统和相关块设备之间的请求。例如,对底层设备驱动程序的读写请求会通过缓冲区缓存来传递。这就允许在其中缓存请求,减少访问物理设备的次数,加快访问速度。以最近使用(LRU)列表的形式管理缓冲区缓存。注意,可以使用sync命令将缓冲区缓存中的请求发送到存储媒体(迫使所有未写的数据发送到设备驱动程序,进而发送到存储设备)。
相关术语如下。
● 挂装:在Linux中将一个文件系统与一个存储设备关联起来的过程称为挂装(mount)。使用mount命令将一个文件系统附着到当前文件系统层次结构中(根)。在执行挂装时,要提供文件系统类型、文件系统和一个挂装点。
● 块设备:块设备就是以块(比如磁盘扇区)为单位收发数据的设备,它们支持缓冲和随机访问(不必顺序读取块,而是可以在任何时候访问任何块)等特性。块设备包括硬盘、CD-ROM和RAM盘。与块设备相对的是字符设备,字符设备没有可以进行物理寻址的媒体。字符设备包括串行端口和磁带设备,只能逐字符地读取这些设备中的数据。
2.1.3 Linux文件系统结构
Linux的文件系统采用阶层式树状目录结构,最上层是“/”,然后在下边创建其他的目录(如表2-1所示),因为Linux允许厂商和个人来修改操作系统,很容易造成目录不统一的情况发生,所以制定了一套规范文件目录的命名及存放标准的文件,这就是:Filesystem Hierarchy Standard(FHS),包括Red Hat厂商在内的发行者都要遵守这个标准,感兴趣的读者可以登录这个网址查看说明:http://www.pathname.com/fhs/。
表2-1 Linux安装时的默认目录
此外,下面补充一下一些比较重要的子目录的用途。
1./etc/init.d
这个目录是用来存放系统或服务器以System V模式启动的脚本,这在以System V模式启动或初始化的系统中常见。比如Fedora/RedHat。
2./etc/xinit.d
如果服务器是通过xinetd模式运行的,它的脚本要放在这个目录下。有些系统没有这个目录,比如Slackware,有些老的版本也没有。在Rehat/Fedora中比较新的版本中存在。
3./etc/rc.d
这是Slackware发行版有的一个目录,是BSD方式启动脚本的存放地。比如定义网卡,服务器开启脚本等。
4./etc/X11
这是X-Windows相关的配置文件存放地。
5./usr/bin
这个目录是可执行程序的目录,普通用户就有权限执行。当我们从系统自带的软件包安装一个程序时,它的可执行文件大多会放在这个目录,比如安装gaim软件包时。相似的目录是/usr/local/bin。有时/usr/bin中的文件是/usr/local/bin的链接文件。
6./usr/sbin
这个目录也是可执行程序的目录,但大多数情况下存放涉及系统管理的命令。只有root权限才能执行。相似目录是/sbin、/usr/local/sbin或/usr/X11R6/sbin等。
7./usr/local
这个目录通常用来存放用户自编译安装软件。一般是通过源码包安装的软件,如果没有特别指定安装目录,一般安装在这个目录中。这个目录下面有子目录。
8./usr/lib
和/lib目录相似,是库文件的存储目录。
9./usr/share
系统共用的东西存放地,比如/usr/share/fonts是字体目录,是用户都共用的。/usr/share/doc和/usr/share/man帮助文件,也是共用的。
10./usr/src
这是内核源码存放的目录,比如下面有内核源码目录,如linux、linux-2.xxx.xx目录等。有的系统也会把源码软件包安装在这里。比如Fedora/Redhat,当我们安装file.src.rpm的时候,这些软件包会安装在/usr/src/redhat相应的目录中。另外redhat的内核源码包的目录位于/usr/src/kernels目录下的某个目录中(只有安装后才会生成相应目录)。
11./var/adm
比如软件包安装信息、日志、管理信息等,在Slackware操作系统中是有这个目录的。在Fedora中好像没有,读者可以去看一下。
12./var/log
系统日志存放,分析日志要看这个目录的东西。
13./var/spool
打印机、邮件、代理服务器等假脱机目录。
2.1.4 /proc文件系统
/proc虚拟文件系统是一个较快且高效率执行系统监控的方法,其主要缺点是必须保持代码分析与/proc文件格式改变的同步。事实表明,Linux内核的改变比/proc文件格式的改变更频繁,所以用/proc虚拟文件系统比用内核模块存在的问题少。
proc文件系统的特点
Linux系统为管理员提供了非常好的方法,使其可以在系统运行时更改内核。而不需要重新引导内核系统,这是通过/proc虚拟文件系统实现的。/proc文件虚拟系统是一种内核和内核模块用来向进程(process)发送信息的机制(所以叫做“/proc”)。这个伪文件系统允许与内核内部数据结构交互,获取有关进程的有用信息,在运行中(on the fly)改变设置(通过改变内核参数)。与其他文件系统不同,/proc存在于内存而不是硬盘中。不用重新启动查看CMOS即可知道系统信息,这就是/proc的作用之一。/proc目录中的主要文件如表2-2所示。
表2-2 /proc目录中的主要文件
每个Linux系统根据软、硬件不同,/proc虚拟文件系统的内容也有些差异。它有三个重要的目录,即net、scsi和sys。sys目录是可写的,可以通过它来访问或修改内核的参数,而net和scsi则依赖于内核配置。例如,如果系统不支持scsi,则scsi目录不存在。其中还有一些以数字命名的目录,它们是进程目录。net目录包括多个ASCII格式的网络伪文件,描述了网络层的部分情况,可以用arp、netstat及route等命令来查询这些文件,其中还有一些以数字命名的进程目录。系统中当前运行的每一个进程都有对应的一个目录在/proc下,以进程的PID号为目录名,它们是读取进程信息的接口。而self目录则是读取进程本身的信息接口,是一个link。
2.1.5 Linux文件系统的组成
在Linux系统内部,一个文件系统是由逻辑块的序列组成的,每块为512个字节。具体组成如图2-2所示。
图2-2 Linux文件系统的内部结构
● 引导块:在Linux文件系统的开头通常有一个扇区存放着一定的程序,用于读入并启动操作系统。每个文件系统都有一个引导块。
● 超级块:记录文件系统的当前状态,如硬盘空间的大小和文件系统的基本信息。
● 索引节点区:存放文件系统的索引节点表,Linux系统中每个文件和目录都占据一个索引节点。文件系统一般从根节点开始。
● 数据区:存放着文件数据和用于文件管理的其他数据。
2.1.6 文件类型
Linux系统中有5 种基本的文件类型:普通文件、目录文件、连接文件、设备文件和管道文件。不论是什么类型的文件,Linux都赋予它一个索引节点。该索引节点包含文件的所有信息,包括磁盘上数据的地址和文件类型等信息。索引节点存储在索引节点表(inode table)中,该表在磁盘格式化时自动分配得到。
1.普通文件
普通文件是用户经常使用的文件,它又分为文本文件和二进制文件。一般的文档和程序都属于普通文件。
● 文本文件:这类文件以文本的ASCII码形式存储在计算机中。它是以“行”为基本结构的一种信息组织和存储方式。
● 二进制文件:这类文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们,只有通过相应的软件才能将其显示出来,二进制文件一般是可执行程序、图形、图像、声音等。
2.目录文件
设计目录文件的主要目的是用于管理和组织系统中的大量文件。Linux系统把目录也看成是文件,称为目录文件,也是文件的一种类型。目录是由操作系统用于形成文件系统树状结构的一个节点单位。目录文件里包含普通文件和下一级的目录,并且包含指向下属文件和子目录的指针。目录文件是为了管理目录而设置的文件。
在C语言里,经常使用指针来编程。同样,Linux也是通过对地址的指针寻址来实现其对目录和文件的管理的。当用mv命令对存在于当前目录中的一个文件重新命名时,所做的事只是改变该文件在目录文件中的说明。如果把一个文件从一个目录移到另一个目录中,所做的事只是改变该文件在目录文件中的指针地址。实际上Linux通过读取索引节点表来检测这种行动,而文件只是被赋予了一个新的索引节点而已。同样,当用rm命令删除文件时,Hnux标记该索引节点是自由的,并把它放回可供使用的空闲索引节点表中。在此,还将简单介绍子目录与父目录的关系:如果一个目录是包含在另外一个目录下的,则这个目录就是它上一级目录的子目录,对应地,上一级目录就是这个目录的父目录。
3.链接文件
硬链接(Hard Link)是指通过索引节点来进行的链接。在Linux的文件系统中,保存在磁盘分区中的文件,不管是什么类型,都给它分配一个编号,称为索引节点号(inode index)。在Linux中,多个文件名指向同一索引节点是存在的。这种链接一般就是硬链接。硬链接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬链接到重要文件,以防止“误删”。其原因如上所述:因为对应该目录的索引节点有一个以上的链接,而只删除一个链接并不影响索引节点本身和其他的链接,只有当最后一个链接被删除后,文件的数据块及目录的链接才会被释放,也就是说,这时文件才会被真正删除。
此外,利用硬链接还能实现文件共享。当一个有硬链接的文件被修改时,所有与这个文件硬链接的文件都同时修改。这样,当两个程序员共同开发一个较大的程序时,两个人可以在一个有硬链接的文件上各自编写自己的程序部分。同时还可以共享他人的成果,从而收到事半功倍的效果,大大提高工作效率。
与硬链接相对应,Lnux系统中还存在另一种链接,称为符号(Symbilc Link)链接,也即软链接。它实际上是特殊文件的一种。在符号链接中,文件实际上是一个文本文件,其中包含有另一文件的位置信息。
4.设备文件
设备文件是Linux系统的很重要的一个特色。Linux系统把每一个I/O设备都看成一个文件,与普通文件一样处理,这样可以使文件与设备的操作尽可能统一。从用户的角度来看,对I/O设备的使用和一般文件的使用一样,不必了解I/O设备的细节。设备文件可以细分为块设备文件和字符设备文件。前者的存取是以字符块为单位的,后者则是以单个字符为单位的。它对应于一种实际设备(终端、磁盘、打印机、网卡等)。
在Linux中,把硬件设备当做文件来管理。每个与Unux系统相连的实际设备(包括磁盘、终端和打印机),都必须在文件系统中表示出来。前面已经提到过,大多数设备文件(即使不是全部)都放在/dev目录中。特殊文件并不包含信息,它们只是操作系统存取输入、输出装置的中介。在此,值得一提的是一种特殊的设备文件,即FIFO(先入先出缓冲区)。它看起来像普通文件,如果向里写入,它们就增长,但是,如果从FIFO读出,它的大小就会缩减。/dev/null即空存储桶,是一个非常有用的特殊设备文件,也称为位桶(bit bucket),你送入/dev/null的任何东西都被忽略,当你不想看到命令的输出结果时,它是很有用的。
Linux系统主要的硬件设备文件如下。
● IDE接口设备:hdX;
● SCSI设备:sdX;
● 打印机:ipX;
● 网卡:ethX;
● 内存:mem。
5.管道文件
管道源自“贝尔实验室”开发的UNIX,Linux继承了这项技术。管道是通过通常的IO接口存取的字节流。管道文件是一种很特殊的文件,主要用于不同进程间的信息传递。当两个进程间需要进行数据或信息传递时,可以通过管道文件实现。一个大型的应用系统,往往需要众多进程协作,进程间通信的重要性显而易见。通常管道建立在调整缓存中。
2.1.7 文件系统的特性
Linux文件系统的特性决定文件的属性,比如我们通过chattr +i来避免某个文件被改动,通过chattr+i来改其为只读文件,在ext2和ext3下是可以的,但在ReiserFS下这样做是不能起任何作用的。不同的文件系统有不同的特性,这种特性往往决定着文件系统文件和目录的属性,这也是我为何创作本书的主要原因。通过本节,我能引出在Linux中文件和目录属性的操作。每个文件系统都有一系列的工具,包括创建、修复、备份等,值得一说的是大多文件系统都有修复工具。
2.1.8 Linux主流文件格式
文件系统指文件存在的物理空间。在Linux系统中,每个分区都是一个文件系统,都有自己的目录层次结构。Linux的最重要特征之一就是支持多种文件系统,这样它更加灵活,并且可以和许多其他种操作系统共存。Virtual File System(虚拟文件系统)使得Linux可以支持多个不同的文件系统。由于系统已将Linux文件系统的所有细节进行了转换,所以Linux核心的其他部分及系统中运行的程序将看到统一的文件系统。Linux的虚拟文件系统允许用户能同时透明地安装许多不同的文件系统。虚拟文件系统是为Linux用户提供快速且高效的文件访问服务而设计的。
随着Linux的不断发展,它所支持的文件格式系统也在迅速扩充。特别是Linux 2.4内核正式推出后,出现了大量新的文件系统,其中包括日志文件系统ext3、ReiserFS、XFSJFS和其他文件系统。Linux系统核心可以支持十多种文件系统类型:JFS、ReiserFS、ext、ext2、ext3、ISO 9660、XFS、Minx、MSDOS、UMSDOS、VFAT、NTFS、HPFS、NFS、SMB、SysV、PROC等。下面介绍Linux下几个最常用的文件系统,其中包括ext、ext2、ext3、JFS、ReiserFS、XFS等。
1.ext
ext是第一个专门开发的Linux文件系统类型,叫做扩展文件系统。它是1992年4月完成的,对Linux早期的发展产生了重要作用。但是,由于其在稳定性、速度和兼容性上存在许多缺陷,现在已经很少使用了。
2.ext2
ext2是为解决ext文件系统的缺陷而设计的可扩展的、高性能的文件系统,它又被称为二级扩展文件系统。ext2是1993年发布的,设计者是Rey Card。它是Linux文件系统类型中使用最多的格式,并且在速度和CPU利用率上较为突出,是GNU/Linux系统中标准的文件系统。它存取文件的性能极好,对于中、小型的文件更显示出优势,这主要得益于其簇快取层的优良设计。ext2可以支持256字节的长文件名,其单一文件大小和文件系统本身的容量上限与文件系统本身的簇大小有关。在常见的Intel x86兼容处理器的系统中,簇最大为4KB,单一文件大小上限为2048GB,而文件系统的容量上限为6384GB。尽管Linux可以支持种类繁多的文件系统,但是2000年以前,几乎所有的Linux发行版都使用ext2作为默认的文件系统。
ext2也有一些问题。它的设计者主要考虑的是文件系统性能方面的问题,而在写入文件内容的同时,并没有写入文件的meta-data(和文件有关的信息,例如权限、所有者及创建和访问时间)。换句话说,Linux先写入文件的内容,然后等到有空的时候才写入文件的meta-data。如果出现写入文件内容之后,在写入文件的meta-data之前系统突然断电,就可能造成文件系统处于不一致的状态。在一个有大量文件操作的系统中出现这种情况会导致很严重的后果。另外,由于目前Linux的2.4内核所能使用的单一分割区最大只有2048GB,因此尽管文件系统的容量上限为6384GB,但是实际上能使用的文件系统容量最大也只有2048GB。
3.ext3
在讲解ext3、JFS、XFS、ReiserFS日志格式文件系统之前,先介绍一下日志式文件系统基础。
日志式文件系统起源于Oracle、Sybase等大型数据库。数据库操作往往是由多个相关的、相互依赖的子操作组成的,任何一个子操作的失败都意味着整个操作的无效性,对数据库数据的任何修改都要恢复到操作以前的状态。Linux日志式文件系统就是由此发展而来的。日志文件系统通过增加一个叫做日志的、新的数据结构来解决这个“fsck”问题。这个日志是位于磁盘上的结构。在对元数据做任何改变以前,文件系统驱动程序会向日志中写入一个条目,这个条目描述了它将要做些什么,所以日志文件具有可伸缩性和健壮性。在分区中保存日志记录文件的好处是:文件系统写操作首先是对记录文件进行操作,若整个写操作由于某种原因(如系统掉电)而中断,则在下次系统启动时就会读日志记录文件的内容,恢复到没有完成的写操作,这个过程一般只需要两三分钟时间。
ext3是由开放资源社区开发的日志文件系统,早期主要开发人员是Stephen Tweedie。ext3被设计成是ext2的升级版本,尽可能方便用户从ext2向ext3迁移。ext3在ext2的基础上加入了记录元数据的日志功能,努力保持向前和向后的兼容性,也就是在保有目前ext2的格式之下再加上日志功能。和ext2相比,ext3提供了更佳的安全性,这就是数据日志和元数据日志之间的不同。ext3是一种日志式文件系统,日志式文件系统的优越性在于由于文件系统都有快取层参与运作,不使用时必须将文件系统卸下,以便将快取层的资料写回磁盘中。因此,每当系统要关机时,必须将其所有的文件系统全部卸下后才能关机。如果在文件系统尚未卸下前就关机(如停电),那么重开机后就会造成文件系统的资料不一致,故这时必须做文件系统的重整工作,将不一致与错误的地方修复。
然而,这个过程是相当耗时的,特别是容量大的文件系统不能百分之百保证所有的资料都不会流失,在大型的服务器上可能会出现问题。除了与ext2兼容之外,ext3还通过共享ext2的元数据格式继承了ext2的其他优点。比如,ext3用户可以使用一个稳固的fsck工具。由于ext3基于ext2的代码,所以它的磁盘格式和ext2的相同,这意味着一个干净卸装的ext3文件系统可以作为ext2文件系统毫无问题地重新挂装。如果现在使用的是ext2文件系统,并且对数据安全性要求很高,这里建议考虑升级使用ext3。
ext3最大的缺点是,它没有现代文件系统所具有的、能提高文件数据处理速度和解压的高性能。此外,使用ext3文件系统要注意硬盘限额问题,在这个问题解决之前,不推荐在重要的企业应用上采用ext3+Disk Quota(磁盘配额)。
4.JFS
JFS是一种提供日志的字节级文件系统。该文件系统主要是为满足服务器(从单处理器系统到高级多处理器和群集系统)的高吞吐量和可靠性需求而设计、开发的。JFS文件系统是为面向事务的高性能系统而开发的。在IBM的AIX系统上,JFS已经过较长时间的测试,结果表明它是可靠、快速和容易使用的。2000年2月,IBM宣布在一个开放资源许可证下移植Linux版本的JFS文件系统。
JFS也是一个有大量用户安装使用的企业级文件系统,具有可伸缩性和健壮性。与非日志文件系统相比,它的突出优点是快速重启能力,JFS能够在几秒或几分钟内就把文件系统恢复到一致状态。虽然JFS主要是为满足服务器(从单处理器系统到高级多处理器和群集系统)的高吞吐量和可靠性需求而设计的,但还可以用于想得到高性能和可靠性的客户机配置,因为在系统崩溃时JFS能提供快速文件系统重启时间,所以它是因特网文件服务器的关键技术。使用数据库日志处理技术,JFS能在几秒或几分钟之内把文件系统恢复到一致状态。而在非日志文件系统中,文件恢复可能花费几小时或几天。
JFS的缺点是,使用JFS日志文件系统在性能上会有一定损失,系统资源占用的比例也偏高,因为当它保存一个日志时,系统需要写许多数据。
5.ReiserFS
ReiserFS的第一次公开亮相是在1997年7月23日,Hans Reiser把他的基于平衡树结构的ReiserFS文件系统在网上公布。ReiserFS 3.6.x(作为Linux 2.4一部分的版本)是由Hans Reiser和他的Namesys开发组共同开发设计的。SuSE Linux也对它的发展有重大的帮助。Hans和他的组员们相信最好的文件系统是能够有助于创建独立的共享环境或命名空间的文件系统,应用程序可以在其中更直接、有效和有力地相互作用。为了实现这一目标,文件系统就应该满足使用者对性能和功能方面的需要。那样使用者就能够继续直接地使用文件系统,而不必建造运行在文件系统之上(如数据库之类)的特殊目的层。
ReiserFS使用了特殊的、优化的平衡树(每个文件系统一个)来组织所有的文件系统数据,这为其自身提供了非常不错的性能改进,也能够减轻文件系统设计上的人为约束。另一个使用平衡树的好处就是,ReiserFS能够像其他大多数的下一代文件系统一样,根据需要动态地分配索引节,而不必在文件系统创建时建立固定的索引节。这有助于文件系统更灵活地适应面临的各种存储需要,同时提供附加的空间有效率。
ReiserFS被看做是一个更加激进和现代的文件系统。传统的UNIX文件系统是按磁盘块来进行空间分配的,对于目录和文件等的查找使用了简单的线性查找。这些设计在当时是合适的,但随着磁盘容量的增大和应用需求的增加,传统文件系统在存储效率、速度和功能上已显得落后。在ReiserFS的下一个版本——Reiser 4,提供了对事务的支持。ReiserFS突出的地方还在于其设计上着眼于实现一些未来的插件程序,这些插件程序可以提供访问控制列表、超级链接,以及其他一些非常不错的功能。在http://www.namesys.com/v4/v4.html中,有Reiser 4的介绍和性能测试。
ReiserFS一个最受批评的缺点是,每升级一个版本都要将磁盘重新格式化一次,而且它的安全性能和稳定性与ext3相比有一定的差距。因为ReiserFS文件系统还不能正确处理超长的文件目录,如果创建一个超过768 字符的文件目录,并使用ls或其他echo命令,将有可能导致系统挂起。在http://www.namesys.com/网站可以了解关于ReiserFS的更多信息。
6.XFS
XFS是一种非常优秀的日志文件系统,它是由SGI于20世纪90年代初开发的。XFS推出后被业界称为先进的、最具可升级性的文件系统技术。它是一个全64位、快速、稳固的日志文件系统,多年用于SGI的IRIX操作系统。当SGI决定支持Linux社区时,它将关键的基本架构技术授权予Linux,以开放资源形式发布了他们自己拥有的XFS的源代码,并开始进行移植。此项工作进展得很快,目前已进入Beta版阶段。作为一个64位文件系统,XFS可以支持超大数量的文件(9000×1GB),可在大型2D和3D数据方面提供显著的性能。XFS有能力预测其他文件系统薄弱环节,同时可在不妨碍性能的情况下增强可靠性和快速的事故恢复。
XFS可为Linux和开放资源社区带来如下新特性。
(1)可升级性
XFS被设计成可升级的,以面对大多数的存储容量和I/O存储需求。XFS可处理大型文件和包含巨大数量文件的大型目录,以满足21 世纪快速增长的磁盘需求。XFS有能力动态地为文件分配索引空间,使系统形成高效支持大数量文件的能力。在它的支持下,用户可使用的文件远远大于现在最大的文件系统。
(2)优秀的I/O性能
典型的现代服务器使用大型的条带式磁盘阵列,以提供达数GB/秒的总带宽。XFS可以很好地满足I/O请求的大小和并发I/O请求的数量。XFS可作为root文件系统,并被LILO支持,也可以在NFS服务器上使用,并支持软件磁盘阵列(RAID)和逻辑卷管理器(Logical Volume Manager,LVM)。由于XFS比较复杂,实施起来有一些难度(包括人员培训等),所以目前XFS主要应用于Linux企业应用的高端。
7.其他文件系统
上面介绍了6种主要文件系统,下面简单介绍一下其他文件系统。
(1)Minix,是Linux支持的第一个文件系统,对用户有很多限制,性能低下,有些没有时间标记,文件名最长l4个字符。Minix文件系统的最大缺点是只能使用64MB的硬盘分区,所以目前已经没有人使用它了。
(2)Xia,是Minix文件系统修正后的版本,在一定程度上解决了文件名和文件系统大小的局限。但是没有新的特色,目前很少有人使用。
(3)ISO 9660,标准CDROM文件系统,通用的Rock Ridge增强系统,允许长文件名。
(4)NFS,Sun公司推出的网络文件系统,允许多台计算机之间共享同一文件系统,易于从所有这些计算机上存取文件。
(5)SysV,是System V/Coherent在Linux平台上的文件系统。
除了上面这些Linux文件系统外,Linux也可以支持基于Windows和Netware的文件系统,例如UMSDOS、MSDOS、VFAT、HPFS、SMB和NCPFS等。兼容这些文件系统对Linux用户也是很重要的,毕竟在桌面环境下Windows文件系统还是很流行的,而Netware网络也有许多用户,Linux用户也需要共享这些文件系统的数据。
(1)UMSDOS,Linux下的扩展MSDOS文件系统驱动,支持长文件名、所有者、允许权限、连接和设备文件。允许一个普通的MSDOS文件系统用于Linux,而且无须为它建立单独的分区。
(2)MSDOS,是在DOS、Windows和某些OS/2操作系统上使用的一种文件系统,其名称采用“8+3”的形式,即8个字符的文件名加上3个字符的扩展名。
(3)VFAT,是Windows 9x和Windows NT/2000下使用的一种DOS文件系统,其在DOS文件系统的基础上增加了对长文件名的支持。
(4)HPFT,高性能文件系统(High Performance File System,HPFS)是微软的LAN Manager中的文件系统,同时也是IBM的LAN Server和OS/2的文件系统。HPFT能访问较大的硬盘驱动器,提供了更多的组织特性,并改善了文件系统的安全特性。
(5)SMB,是一种支持Windows for Workgroups、Windows NT和Lan Manager的基于SMB协议的网络操作系统。
(6)NCPFS,是一种Novell NetWare使用的NCP协议的网络操作系统。
(7)NTFS,是Windows NT/2000操作系统支持的、一个特别为网络和磁盘配额、文件加密等管理安全特性设计的磁盘格式。
2.2 查看当前Linux支持的文件类型
不同版本的Linux所支持的文件系统类型和种类都有所不同,如何知道自己使用的Linux发行版的文件系统类型呢?下面以RHEL 5.0为例,讲解如何操作。
以超级用户权限登录Linux,进入/fs目录,执行下面命令:
#ls
注意,不同Linux发行版本的fs目录的位置可能有些不同。会显示当前系统所支持的文件系统种类。从图2-3中可以看到,笔者使用的RHEL 5.0支持的文件系统非常多。
图2-3 RHEL 5.0支持的文件系统类型
文件系统是操作系统用于明确磁盘或分区上的文件的方法和数据结构,即在磁盘上组织文件的方法。文件系统是整个操作系统中重要的组成部分,是操作系统正常运行的基本条件。了解Linux文件系统对于深入学习、研究Linux是非常重要的。
2.2.1 ls:显示文件名
作用:ls命令用于显示目录内容,类似DOS下的dir命令,它的使用权限是所有用户。
格式:ls [选项] 文件名
[选项]主要参数如下。
● -a:列出目录下的所有文件,包括以“.”开头的隐含文件。
● -b:把文件名中不可输出的字符用反斜杠加字符编号(就像在C语言里一样)的形式列出。
● -c:输出文件的i节点的修改时间,并以此排序。
● -d:将目录像文件一样显示,而不是显示其下的文件。
● -e:输出时间的全部信息,而不是输出简略信息。
● -f -U:对输出的文件不排序。
● -g:无用。
● -i:输出文件的i节点的索引信息。
● -k:以K字节的形式表示文件的大小。
● -l:列出文件的详细信息。
● -m:横向输出文件名,并以“,”作为分隔符。
● -n:用数字的UID,GID代替名称。
● -o:显示文件的除组信息外的详细信息。
● -p-F:在每个文件名后附上一个字符以说明该文件的类型,“*”表示可执行的普通文件;“/”表示目录;“@”表示符号链接;“|”表示FIFOs;“=”表示套接字(sockets)。
● -q:用?代替不可输出的字符。
● -r:对目录反向排序。
● -s:在每个文件名后输出该文件的大小。
● -t:以时间排序。
● -u:以文件上次被访问的时间排序。
● -x:按列输出,横向排序。
● -A:显示除“.”和“..”外的所有文件。
● -B:不输出以“~”结尾的备份文件。
● -C:按列输出,纵向排序。
● -G:输出文件的组的信息。
● -L:列出链接文件名而不是链接到的文件。
● -N:不限制文件长度。
● -Q:把输出的文件名用双引号括起来。
● -R:列出所有子目录下的文件。
● -S:以文件大小排序。
● -X:以文件的扩展名(最后一个“.”后的字符)排序。
● -1:一行只输出一个文件。
● --color=no:不显示彩色文件名。
● --help:在标准输出上显示帮助信息。
● --version:在标准输出上输出版本信息并退出。
[大小]可以是以下的单位(单位前可加上整数)。
kB:1000,K 1024,mB:1000000,M 1048576,还有G、T、P、E、Z、Y。
ls命令应用举例如下。
(1)ls命令的颜色选项
ls命令是Linux系统使用频率最高的命令,它的参数也是Linux命令中最多的。使用ls命令时会有几种不同的颜色,其中蓝色表示是目录,绿色表示是可执行文件,红色表示是压缩文件,浅蓝色表示是链接文件,加粗的黑色表示符号链接,灰色表示是其他格式文件。ls最常使用的是ls -l。
(2)窍门
要想看到ls命令的所有选项,你可以通过在shell提示下使用命令man ls来阅读其说明书页。如果你想打印这个说明书页,可以在shell提示下,使用命令man ls | col -b | lpr。
(3)使用命令命令ls -a
现在你将会看到以点起首的文件,如图2-4所示。
图2-4 带有-a选项的ls命令
隐藏文件多数是配置文件。它们给程序、窗口管理器、shell等设置首选项。它们被隐藏的目的是防止用户对其无意的篡改。当你在目录中搜寻某项事物时,你一般不是在寻找这些配置文件,因而当你在shell下查看目录内容时把它们隐藏起来可以避免屏幕的拥挤。使用ls -a命令来查看所有的文件会向你显示大量的细节,但是通过添加更多的选项,你可以看到更多的细节。如果你想查看一个文件或目录的大小、创建时间等,在ls -a命令后面添加long(长)选项(-l)就可以了。这个命令显示了文件创建的日期、它的大小、所有者、权限等。当你想使用ls命令来查看目录内容时,你不必位于该目录下。例如,要在你的主目录中查看/usr目录中的内容,应使用命令:
ls -al /usr ls -al /usr 总计 268 drwxr-xr-x 15 root root 40962007-11-30 . drwxr-xr-x 24 root root 4096 08-02 07:10 .. drwxr-xr-x 2 root root 61440 08-02 08:46 bin drwxr-xr-x 2 root root 40962006-10-11 etc drwxr-xr-x 2 root root 40962006-10-11 games drwxr-xr-x 120 root root 122882007-07-16 include drwxr-xr-x 3 root root 40962007-11-30 java drwxr-xr-x 6 root root 40962007-01-17 kerberos drwxr-xr-x 110 root root 614402007-10-21 lib drwxr-xr-x 12 root root 40962007-08-23 libexec drwxr-xr-x 15 root root 40962007-11-30 local drwxr-xr-x 2 root root 16384 08-02 07:11 sbin
(4)查看文件被修改或被访问的时间
我们通过查看文件的属性时,会发现它的时间标记,比如下面的08-21 22:26。这个时间并不代表文件被创建的时候,而是代表文件被访问或被修改的时间。文件被修改的时间比较好理解,比如我们可以用编辑器来修改文本文件,然后保存一下,这样文件的时间就变了。
ls -l adduml02.sh -rwxr-xr-x 1 root root 545 08-21 22:26 adduml02.sh
2.2.2 cat:显示文本文件内容
作用:将[文件]或标准输入组合输出到标准输出。
格式:用法:cat [选项] [文件]...
选项如下。
● -A,--show-all:等价于-vET。
● -b,--number-nonblank:对非空输出行编号。
● -e:等价于-vE。
● -E,--show-ends:在每行结束处显示$。
● -n,--number:对输出的所有行编号。
● -s,--squeeze-blank:不输出多行空行。
● -t:与-vT等价。
● -T,--show-tabs:将跳格字符显示为^I。
● -u:(被忽略)。
● -v,--show-nonprinting:使用^和M-引用,除了LFD和TAB之外。
● --help:显示此帮助信息并退出。
● --version:输出版本信息并退出。
如果[文件]缺省,或者[文件]为-,则读取标准输入。
实例应用如下。
(1)显示文本文件的内容
cat命令一个最简单的用处是显示文本文件的内容。例如,要查看README文本文件的内容,可以使用命令:
$ cat README
(2)合并文件
有时需要将几个文件处理成一个文件,并将这种处理的结果保存到一个单独的输出文件。
$cat README INSTALL Changlog > File1
把README、INSTALL和Changlog的文件内容加上行号(空白行不加)之后,将内容附加到一个新文本文件File1。
(3)对行进行编号
这种功能对于程序文档的编制及法律和科学文档的编制很方便。打印在左边的行号使得参考文档的某一部分变得容易。这在编程、科学研究、业务报告,甚至立法工作中都是非常重要的。对行进行编号功能有两个选项:“-b”选项(对非空白行进行编号)和“-n”选项(对所有行进行编号),如图2-5所示。
图2-5 使用cat命令给一个文本文件进行编号
2.2.3 rm:删除文件
作用:删除指定的<文件>。
格式:rm [选项]...文件...
选项如下。
● -d,--directory:删除<文件>,即便该文件可能是非空目录(只限超级用户;仅当你的系统支持“unlink”非空目录时才有效)。
● -f,--force:略过不存在的文件,绝不提示。
● -i,--interactive:进行任何删除操作前必须先确认。
● --no-preserve-root:不特殊对待“/”(默认值)。
● --preserve-root:不允许在“/”上递归操作。
● -r,-R,--recursive:递归删除目录及其内容。
● -v,--verbose:详细显示进行的步骤。
● --help:显示此帮助信息并退出。
● --version:输出版本信息并退出。
默认情况下,rm不删除目录。使用--recursive(-r或-R)选项可以删除每个列出的目录及其下面的内容。
应用实例如下。
(1)使用rm命令要小心因为一旦文件被删除,恢复比较困难。为了防止这种情况的发生,可以使用i选项来逐个确认要删除的文件。如果用户输入y,文件将被删除。如果输入任何其他东西,文件则不会删除。
(2)如果任何一级的目录有文件,要用到rm -rf命令强制删除。
不过用rm -rf删除时有点不安全,还是用rf -ri比较好一点,因为在删除的时候,会有警告提示。这对于安全操作来说是很重要的。
2.2.4 less:分屏显示文件
作用:less命令的功能几乎和more命令一样,也用来按页显示文件,不同之处在于less命令在显示文件时,允许用户既可以向前又可以向后翻阅文件。
格式:less [选项] 文件
选项如下。
● -c:从顶部(从上到下)刷新屏幕,并显示文件内容。而不是通过底部滚动完成刷新。
● -f:强制打开文件,二进制文件显示时,不提示警告。
● -i:搜索时忽略大小写,除非搜索串中包含大写字母。
● -I:搜索时忽略大小写,除非搜索串中包含小写字母。
● -m:显示读取文件的百分比。
● -M:显法读取文件的百分比、行号及总行数。
● -N:在每行前输出行号。
● -p pattern:搜索pattern,比如在/etc/profile搜索单词MAIL,就用less -p MAIL /etc/profile。
● -s:把连续多个空白行作为一个空白行显示。
● -Q:在终端下不响铃。
● 回车键:向下移动一行。
● y:向上移动一行。
● 空格键:向下滚动一屏。
● b:向上滚动一屏。
● d:向下滚动半屏。
● h:less的帮助。
● u:向上洋动半屏。
● w:可以指定显示哪行开始显示,是从指定数字的下一行显示;比如指定的是6,那么就从第7行显示。
● g:跳到第一行。
● G:跳到最后一行。
● p n%:跳到n%,比如10%,也就是说到整个文件内容的10%处开始显示。
● /pattern:搜索pattern,比如/MAIL表示在文件中搜索MAIL单词。
● v:调用vi编辑器。
● q:退出less。进入less后,我们得学操作,这样更方便我们查阅文件内容;最应该记住的命令就是q,它能让less终止查看文件退出。
● !command:调用Shell,可以运行命令。比如!ls显示当前列当前目录下的所有文件。
less帮助截图如图2-6所示。
图2-6 less帮助截图
2.2.5 cp:复制文件
作用:文件或目录的复制。
格式:cp [参数选项] 源文件或目录 目标文件或目录
注:参数是可选的,常用参数比如 -r,-R,-p,-i。
选项如下。
● -a:等同于-dpR参数一起使用。在复制过程中尽可能保留源文件或目录的属性。
● -b:给被覆盖的文件做备份。比如我们把file1复制到file2时,如果file2存在,我们把file2覆盖掉,用这个参数就能同时生成一个file2~的文件,注意文件名后有~结尾。
● -d:不间接引用符号链接,保持源文件和目标文件之间的硬链接关系。
● -f:删除已存在的目标文件。
● -i:覆盖已存在的目标文件之前给出警告提示,这是人机交互的选项。
● -l:建立文件硬链接,而不是复制。
● -p:保存源文件或目录的最后修改时间和模式,比如要保持目标目录或文件的属主、组、权限和最后访问(或修改)时间。
● -R:复制目录时,包括此目录下所有的子目录和文件。
● -s:建立源文件的符号链接,而不是复制源文件。源文件名必须用绝对路径。
● -r:复制目录时,包括此目录下所有的子目录和文件;-r选项不同于-R之处在于尝试打开目的地文件前先删除已存在的目的地文件。
● -i:人机交互模式,显示覆盖已存在的文件或目录的警告信息。
● -v:在复制之前,输出每个文件的名字。
● --help:查看帮助。
应用实例如下。
(1)参数-i的示例
# cp -i Kernel.rpm Plist
cp:是否覆盖“Plist”? y。
人机交互在数-i的运用,如果源文件复制到目标文件,如果目标文件存在,则提示警告。
(2)参数-a的示例及说明
把源目录复制到另外的一个目标,相当于克隆了一个目录,源目录和目标目录在用户组、权限及修改或访问时间保持一致。
# cp -a mydir youdir
复制目录mydir到youdir,如果yourdir目录不存在,则创建。并且把mydir中所有的文件下级子目录都复制到yourdir目录中。也就是说mydir目录的文件和youdir是一样的。-a参数等同于-dpR,并且源目录和目标目录的属性(用户组、权限、最后访问及修改时间)都一致。
(3)参数-b的示例应用
把源文件复制为目标文件;并且尝试-b参数的运用;
# cp fonts.scale fonts.dir把一个文件复制为另一个文件。
# cp -bi fonts.scale fonts.dir cp:是否覆盖“fonts.dir”? y
注:因为用了-i参数,如果目标文件存在,则报警提示。
2.2.6 mv:更改文件名
作用:mv可以移动一个文件(或目录)到另一个文件(或目录),如果文件(或目录)不存在,则创建它。其实mv这个过程也可以理解为改名过程,所以说mv工具能修改文件名和目录名。
格式:mv [选项]... [-T] 源 目的
或:mv [选项]... 源... 目录
或:mv [选项]... -t目录 源...
选项如下。
● -b或--backup:若需覆盖文件,则覆盖前先行备份。
● -f或--force:若目标文件或目录与现有的文件或目录重复,则直接覆盖现有的文件或目录。
● -i或--interactive:覆盖前先行询问用户。
● -S<附加字尾>或--suffix=<附加字尾>:与-b参数一并使用,可指定备份文件所要附加的字尾。
● -u或--update:在移动或更改文件名时,若目标文件已存在,且其文件日期比源文件新,则不覆盖目标文件。
● -v或--verbose:执行时显示详细的信息。
● -V=<方法>或--version-control=<方法>:与-b参数一并使用,可指定备份的方法。
● --help:显示帮助。
● --version:显示版本信息。
应用实例如下。
(1)移动crodw.sh到23.sh
其实就是把文件名改为123.sh:
mv crodw.sh 23.sh
(2)mv修改目录
mv是把文件(或目录)从一个地方移到另一个地方。如果另一地方没有和源文件(或目录)同名的,就创建。这也相当于改名:
# mv kernel/ kernelBak1
2.2.7 grep:查找字符串
作用:查找文件里符合条件的字符串。
格式:grep [选项] <pattern> <files>
选项如下。
● -E:每个模式作为一个扩展的正则表达式对待。
● -F:每个模式作为一组固定字符串对待(以新行分隔),而不作为正则表达式。
● -b:在输出的每一行前显示包含匹配字符串的行在文件中的字节偏移量。
● -c:只显示匹配行的数量。
● -I:比较时不区分大小写。
● -h:在查找多个文件时,指示grep不要将文件名加入到输出之前。
● -l:显示首次匹配串所在的文件名并用换行符将其隔开。当在某文件中多次出现匹配串时,不重复显示此文件名。
● -n:在输出前加上匹配串所在行的行号(文件首行行号为1)。
● -v:只显示不包含匹配串的行。
● -x:只显示整行严格匹配的行。
● -e expression:指定检索使用的模式。用于防止以“-”开头的模式被解释为命令选项。
● -f expfile:从expfile文件中获取要搜索的模式,一个模式占一行。
<pattern> 表示正则表达式。
正则表达式是Linux/UNIX系统中非常重要的概念。正则表达式(也称为“regex”,“regexp”)是一个可以描述一类字符串的模式(Pattern)。如果一个字符串可以用某个正则表达式来描述,我们就说这个字符串和该正则表达式匹配(Match)。这和DOS中用户可以使用通配符“*”代表任意字符类似。在Linux系统中,正则表达式通常被用来查找文本的模式,以及对文本执行“搜索”/“替换”操作和其他功能。
实例应用如下。
(1)查找文件“file.php”中是否包含字符串“html”,使用命令:
# grep 'html' file.php
(2)检查/etc/passwd文件中是否有可疑用户。
Linux中/etc/passwd文件是存储系统用户密码等重要信息的文件,黑客入侵系统后往往会使用在passwd文件中增加特权用户的方法为自己留个后门。所以,我们要经常查看,如果你的系统用户较少,你可以采用直接查看passwd文件的方法,命令为“cat /etc/passwd”。如果你的系统有成百上千个用户,那么直接查看就不行了,不过我们只要检测其中是否有UID为0的特权用户就行了,这时可以使用以下命令来实现:
# grep '0:0' /etc/passwd
说明:grep指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设grep指令会把含有范本样式的那一列显示出来。若不指定任何文件名称,或是所给予的文件名为“-”,则grep指令会从标准输入设备读取数据。要用好grep这个工具,其实就是要写好正则表达式。下面是正则表达式应用实例。
(3)通过管道过滤ls -l输出的内容,只显示以a开头的行。
ls -l | grep '^a'
(4)显示所有以d开头的文件中包含test的行。
$ grep 'test' d*
(5)显示在aa,bb,cc文件中匹配test的行。
$ grep 'test' aa bb cc
(6)显示所有包含每个字符串至少有5个连续小写字符的字符串的行。
$ grep ' [a-z] ' aa
2.2.8 head:显示文件头部
作用:head是显示一个文件的内容的前多少行。
格式:head [选项][文件]
选项如下。
● -c:处理文件前面指定字节数,加b(512字节块)、k(KB数)、m(MB数)。
● -n:显示文件头n行内容。
● -p:处理多个文件时不显示文件头信息。
● -v:处理多个文件时显示文件头信息。
应用实例如下。
(1)显示/etc/profile的前10行内容:
# head -n 10 /etc/profile
(2)将/etc/named.conf中前3行的内容发送至标准输出,使用命令:
$ head -n 3 /etc/ named.conf /etc/named.conf <== // generated by named-bootconf.pl options {
说明:命令“head file1 file2 file3”和命令“cat file1 file2 file3 | head”之间有重大差别。前者将打印每个文件指定行数的内容,不同文件的内容之间用头信息隔开,头信息以“==>”后跟文件名开头。后者将打印由cat命令后所列文件组成的输入流中指定行数的内容,但将把输入流作为单个文件对待。
2.2.9 tail:显示文件尾部
作用:head显示一个文件内容的最后多少行。
格式:head [选项][文件]
选项如下。
● -b:列出辨识结果时,不显示文件名称。
● -c:处理文件末尾指定字节数,加b(512字节块)、k(KB数)、m(MB数)。
● -n:显示文件末尾n行内容。
● -p:处理多个文件时不显示文件头信息。
● -f:如果文件大小在增长的话,tail将随文件增长而一直显示。
● -v:输出“==>文件名<==”形式。
(1)显示/etc/profile的最后5行内容:
#tail -n 5 /etc/profile
(2)将/etc/named.conf中后3行的内容发送至标准输出并显示头信息,使用命令:
$tail -n 3-v /etc/named.conf ==> /etc/named.conf <== }; include "/etc/rndc.key";
说明:如果tail正在读取的文件不止一个,那么各行内容之间将用标准头信息隔开,以指明它们来自哪个文件,标准头信息以“==>”开头,这个选项用于监视系统日志非常合适。例如,在单独的终端窗口中执行的“tail -f /var/log/access.log”将持续打印每次点击后新添加的Apache访问日志条目,一直到你用“Ctrl+C”停止它为止。
2.2.10 sort:按顺序显示文件内容
作用:按顺序显示文件内容。
格式:sort [选项]...[文件]...
选项如下。
● -b:忽略每行前面开始的空格字符。
● -c:检查文件是否已经按照顺序排序。
● -d:排序时,除了英文字母、数字及空格字符外,忽略其他的字符。
● -f:排序时,将小写字母视为大写字母。
● -i:排序时,除了040~176之间的ASCII字符外,忽略其他的字符。
● -m:将几个排序好的文件进行合并。
● -M:作为月份比较。
● -n:依照数值的大小排序。
● -o<输出文件>:将排序后的结果存入指定的文件。
● -r:以相反的顺序来排序。
● -t<分隔字符>:指定排序时所用的栏位分隔字符。
● +<起始栏位>-<结束栏位>:以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。
说明:sort命令有许多非常实用的选项,这些选项最初是用来对数据库格式的文件内容进行各种排序操作的。实际上,sort命令可以被认为是一个非常强大的数据管理工具,用来管理内容类似数据库记录的文件。sort命令将逐行对文件中的内容进行排序,如果两行的首字符相同,该命令将继续比较这两行的下一个字符,如果还相同,将继续进行比较。如不指定输入文件,使用“-”,则表示排序内容来自标准输入。sort排序是根据从输入行抽取的一个、多个关键字进行比较来完成的。排序关键字定义了用来排序的最小的字符序列。默认情况下以整行为关键字按ASCII字符顺序进行排序。
实例应用如下。
(1)如果你想对密码文件进行排序,就可以使用下列命令:
# sort /etc/passwd > /etc/passwd-new # mv /etc/passwd-new /etc/passwd
注意 不能将输出直接发送到输入文件,因为这会破坏输入文件。这就是为何需要将它发送到临时文件中,然后将该文件重命名为/etc/passwd的原因。如果想倒转排序的次序,则应当使用-r选项。你还可以用-u选项来禁止打印相同的行。
(2)用“sort -m”排序合并多个日志。
许多大型的Web服务使用DNS轮循来实现负载均衡。对于使用多个同样角色的服务器做前台的Web服务,多个服务器的分布使得日志的分析统计也变得有些麻烦。可以使用sort合并:
sort -m -t " " -k 4-o log_all log1 log2 log3
2.2.11 uniq:忽略文件中的重复行
作用:文件经过处理后在它的输出文件中可能会出现重复的行。例如,使用cat命令将两个文件合并后,再使用sort命令进行排序,就可能出现重复行。这时可以使用uniq命令将这些重复行从输出文件中删除,只留下每条记录的唯一样本。
格式:uniq [选项]...[输入 [输出]]
选项如下。
● -c:显示输出中,在每行行首加上本行在文件中出现的次数。它可取代-u和-d选项。
● -d:只显示重复行。
● -u:只显示文件中不重复的各行。
● -n:前n个字段与每个字段前的空白一起被忽略。一个字段是一个非空格、非制表符的字符串,彼此由制表符和空格隔开(字段从0开始编号)。
● +n:前n个字符被忽略,之前的字符被跳过(字符从0开始编号)。
● -f n:与-n相同,这里n是字段数。
● -s n:与+n相同,这里n是字符数。
应用实例如下。
(1)显示文件example中不重复的行。
# uniq - u example
(2)显示文件example中不重复的行,从第2个字段的第2个字符开始做比较。
#uniq - u -1 +1 example
2.2.12 diff:比较两个文件
作用:diff命令可以找出两个文件的不同点。
使用权限:所有用户。
格式:diff [选项] 源文件 目标文件
选项如下。
● -<行数>:指定要显示多少行的文本。此参数必须与-c或-u参数一并使用。
● -a或--text:diff预设只会逐行比较文本文件。
● -b或--ignore-space-change:不检查空格字符的不同。
● -B或--ignore-blank-lines:不检查空白行。
● -c:显示全部内文,并标出不同之处。
● -C<行数>或--context<行数>:与执行"-c-<行数>"指令相同。
● -d或--minimal:使用不同的演算法,以较小的单位来做比较。
● -D<巨集名称>或ifdef<巨集名称>:此参数的输出格式可用于前置处理器巨集。
● -e或--ed:此参数的输出格式可用于ed的script文件。
● -f或-forward-ed:输出的格式类似于ed的script文件,但按照原来文件的顺序显示不同处。
● -H或--speed-large-files:比较大文件时,可加快速度。
● -l<字符或字符串>或--ignore-matching-lines<字符或字符串>:若两个文件在某几行有所不同,而这几行同时都包含了选项中指定的字符或字符串,则不显示这两个文件的差异。
● -i或--ignore-case:不检查大小写的不同。
● -l或--paginate:将结果交由pr程序来分页。
● -n或--rcs:将比较结果以RCS的格式来显示。
● -N或--new-file:在比较目录时,若文件A仅出现在某个目录中,预设会显示如下内容。
Only in目录:文件A若使用-N参数,则diff会将文件A与一个空白的文件进行比较。
● -p:若比较的文件为C语言的程序码文件,显示差异所在的函数名称。
● -P或--unidirectional-new-file:与-N类似,但只有当第二个目录包含了一个第一个目录所没有的文件时,才会将这个文件与空白的文件做比较。
● -q或--brief:仅显示有无差异,不显示详细的信息。
● -r或--recursive:比较子目录中的文件。
● -s或--report-identical-files:若没有发现任何差异,仍然显示信息。
● -S<文件>或--starting-file<文件>:在比较目录时,从指定的文件开始比较。
● -t或--expand-tabs:在输出时,将tab字符展开。
● -T或--initial-tab:在每行前面加上tab字符以便对齐。
● -u,-U<列数>或--unified=<列数>:以合并的方式来显示文件内容的不同。
● -v或--version:显示版本信息。
● -w或--ignore-all-space:忽略全部的空格字符。
● -W<宽度>或--width<宽度>:在使用-y参数时,指定栏宽。
● -x<文件名或目录>或--exclude<文件名或目录>:不比较选项中所指定的文件或目录。
● -X<文件>或--exclude-from<文件>:你可以将文件或目录类型存成文本文件,然后在=<文件>中指定此文本文件。
● -y或--side-by-side:以并列的方式显示文件的异同。
● --help:显示帮助。
● --left-column:在使用-y参数时,若两个文件某一行内容相同,则仅在左侧的栏位显示该行内容。
● --suppress-common-lines:在使用-y参数时,仅显示不同之处。
说明:diff以逐行的方式,比较文本文件的异同处。如果源文件和目标文件都是目录,则diff比较两个目录中相应的文件,依照字母次序排序。diff的输出格式有三种,包括列举模式、命令模式和上下文模式,其中命令模式又分为两种,即ed命令模式和RCS(Revision Control System,版本控制系统)命令模式。
实例应用如下。
● 使用并排(side-by-side)格式查看文件差异,如图2-7所示。
图2-7 并排(side-by-side)格式输出
使用并排(side-by-side)格式可以直观比较源代码文件的差异。尽管出现了截行,还是可以非常清楚地显示两个文件的区别。-W选项指定输出列的宽度。diff接受这个宽度,并且分配给两个文件各40行。字符“>”表示该行在目的文件中,“<”表示该行在源文件中。字符“|”标记出两个文件中不相同的行。
2.2.13 diffstat命令:diff结果的统计信息
作用:diffstat读取diff的输出结果,然后统计各文件的插入、删除、修改等差异计量。
格式:diffstat [选项] [文件]
● -n<文件名长度>:指定文件名长度,指定的长度必须大于或等于所有文件中最长的文件名。
● -p<文件名长度>:与-n参数相同,但此处的<文件名长度>包括了文件的路径。
● -w:指定输出时栏位的宽度。
● -V:显示版本信息。
应用实例如下。
比较两个文件:
#diffstat 1.txt 2.txt 0 files changed
2.2.14 file:测试文件内容
命令作用:通过探测文件内容来判断文件类型。
格式:file [选项] 文件名
选项如下。
● -v:在标准输出后显示版本信息,并且退出。
● -z:探测压缩过的文件类型。
● -L:直接显示符号链接所指向的文件的类型。
● -c:详细显示指令的执行过程,便于排错或分析程序执行的情形。
● -f:从文件namefile中读取要分析的文件名列表。
说明:file命令可以知道某个文件究竟是二进制(ELF格式)的可执行文件,还是shell脚本文件,或者是其他格式的文件。file能识别的文件类型有目录、shell脚本、英文文本、二进制可执行文件、C语言源文件、文本文件、DOS的可执行文件。file命令能探测包括图形、音频、视频等在内的多媒体文件类型。
如果我们看到一个没有后缀的文件TRACK11,可以使用下面命令:
$ file TRACK11 track11: MP2, 112 kBits, 44.1 kHz, Stereo
此时系统显示这是一个立体声文件。
2.2.15 echo:显示文本
格式:echo [-ne][字符串]
参数如下。
● -n不要在最后自动换行。
● -e若字符串中出现以下字符,则特别加以处理,而不会将它当成一般参数。
文字输出:
➢ \a发出警告声;
➢ \b删除前一个字符;
➢ \c最后不加上换行符号;
➢ \f换行但光标仍旧停留在原来的位置;
➢ \n换行且光标移至行首;
➢ \r光标移至行首,但不换行;
➢ \t插入tab;
➢ \v与\f相同;
➢ \\插入\字符;
➢ \nnn插入nnn(八进制)所代表的ASCII字符。
● --help显示帮助。
● --version显示版本信息。
应用实例如下。
(1)echo显示字符串。
普通字符串可以在echo后直接输入字符串,但这样当要输出某些字符(如“\”)时会有问题(这种写法下,“\”是被当做继行符处理过滤掉的,要输出一个“\”必须打“\\”,跟C语言printf输出的要求相像),所以一般最好用'string'或"string"的格式,这样即使是“\”也可以输出,方便直观。
#echo hello world hello world #echo hello\ world hello world #echo hello\\ world hello\ world #echo 'hello\\ world' 或者: echo "hello\\ world" hello\\ world
(2)echo的转义显示:加上-e参数输出多行。
#echo -e 'hello\nworld' hello world
(3)输出ASCII字符:echo -e \NNN(NNN为ASCII字符的八进制码号,不符合八进制的将会按照字面意义进行打印)。
#echo -e '\61 \62 \101 \141'
2.2.16 date:显示日期和时间
作用:显示或设置系统时间与日期。
格式:date [选项] 显示时间格式(以+开头,后面接格式)
date设置时间格式。
命令中各选项的含义分别如下。
● -d datestr, --date datestr:显示由datestr描述的日期。
● -s datestr, --set datestr:设置datestr描述的日期。
● -u, --universal:显示或设置通用时间。
➢ %H:小时(以00~23来表示)。
➢ %I:小时(以01~12来表示)。
➢ %K:小时(以0~23来表示)。
➢ %l:小时(以0~12来表示)。
➢ %M:分钟(以00~59来表示)。
➢ %P:AM或PM。
➢ %r:时间(含时分秒,小时以12小时AM/PM来表示)。
➢ %s:总秒数。起算时间为1970-01-01 00:00:00 UTC。
➢ %S:秒(以本地的惯用法来表示)。
➢ %T:时间(含时分秒,小时以24小时制来表示)。
➢ %X:时间(以本地的惯用法来表示)。
➢ %Z:市区。
➢ %a:星期的缩写。
➢ %A:星期的完整名称。
➢ %b:月份英文名的缩写。
➢ %B:月份的完整英文名称。
➢ %c:日期与时间。只输入date指令也会显示同样的结果。
➢ %d:日期(以01~31来表示)。
➢ %D:日期(含年月日)。
➢ %j:该年中的第几天。
➢ %m:月份(以01~12来表示)。
➢ %U:该年中的周数。
➢ %w:该周的天数,0代表周日,1代表周一,依此类推。
➢ %x:日期(以本地的惯用法来表示)。
➢ %y:年份(以00~99来表示)。
➢ %Y:年份(以四位数来表示)。
➢ %n:在显示时,插入新的一行。
➢ %t:在显示时,插入tab。
➢ MM:月份(必要)。
➢ DD:日期(必要)。
➢ hh:小时(必要)。
➢ mm:分钟(必要)。
➢ CC:年份的前两位数(选择性)。
➢ YY:年份的后两位数(选择性)。
➢ ss:秒(选择性)。
● -d<字符串>:显示字符串所指的日期与时间。字符串前后必须加上双引号。
● -s<字符串>:根据字符串来设置日期与时间。字符串前后必须加上双引号。
● -u:显示GMT。
● --help:在线帮助。
● --version:显示版本信息。
说明:只有超级用户才有权限使用date命令设置时间,一般用户只能使用date命令显示时间。
应用实例如下。
显示当前时间:
#date 2008年08月02日星期六17:19:27 CST
2.2.17 script:记录Linux会话信息
作用:script可用来记录执行过的所有命令及命令的输出。
格式:script [选项] 文件
选项如下。
● -a:用于将记录append到文件,若不用则覆盖。
● -t可以记录每次敲击键盘的CPU时间。比如做批处理等,通过查看filename2找到两次间隔时间很大的,就是作业执行的准确时间。
说明:许多系统管理员都知道保留一个包含各种任务、配置改变等活动日志的重要性。对一些组织而言,保留“我做了这件事”或“约翰做了那件事”的简单日志就已足够;但另一些组织则需要记录所有改变。对终端输出进行复制粘贴可能非常乏味,我们使用一个叫做script的鲜为人知的程序来解决这个问题,它是大多数Linux产品util-linux软件包的一部分。script记录会话的一切内容:你输入的内容和你看到的内容。它甚至记录颜色。因此,如果你的命令提示符或程序输出中包含颜色,script将记录它。
应用实例如下。
(1)要使用script,简单执行以下命令:
$ script
默认情况下,它向当前目录的typescript文件中写入内容。然后,你输入的一切内容都被记录到那个文件中。要往另一个文件中记录日志,只需使用script/path/to/file命令。完成记录后,输入exit退出。这个命令将关闭script会话并保存文件。可以使用cat或其他任何程序来检查日志文件。使用script的缺点在于,它记录所有特殊的字符。因此你输入的文件中将充满控制字符和ANSI转义序列。你可以在script中使用一个非常简单的shell来解决这个问题:
$ SHELL=/bin/sh PS1="$ " script
使用script时,不要使用交互式程序或处理窗口的程序,如vior top。它们会破坏会话的输出结果。另外,日志文件会记录你使用的任何命令行程序和你完成一项任务所采取的步骤。如果你需要在脚本中编辑一个文件,可以考虑退出script会话,然后用script -a(它在旧会话后添加新会话)对文件进行编辑后再重新启动会话。
(2)script -a filename1-t 2>filename2
退出命令:exit
若要查看记录结果,用cat filename即可,filename1和filename2可以是同一个文件。
2.2.18 apropos:搜索关键字
作用:在whatis资料库中搜寻特定字串。
格式:apropos关键字
应用实例如下。
要“查找”文件,又不知道用什么命令,你可以输入下面的命令:
$apropos search
其他部分可以根据实际情况删除或增加。
2.2.19 locate:搜索文件
作用:locate用于查找符合条件的文件,它会去保存文件与目录名称的数据库内查找符合范本样式条件的文件或目录。
格式:locate [选项] 相关字
重要选项如下。
● -u,-U:<dir>建立数据库,-u会由根目录开始,-U则可以指定开始的位置。
● -e <dir>:将<dir>排除在寻找的范围之外。
● -l <level>:如果<level>是1,则激活安全模式。
● -f <filetype>:将特定的文件目录排除在外。
● -q:安静模式,不会显示任何错误信息。
● -n:<num>至多显示<num>个输出。
● -r:<reg>使用正规表达式<reg>作为寻找的条件。
● -o:<file>指定数据库的名称。
● -d:<dir>指定数据库的路径。
说明:有时候,往往知道某一文件或目录存在,却不知该到哪里去找到它,这时可以使用locate命令来搜寻文件、目录。同find命令相比较,locate命令从数据库中查找,而不是每次搜索文件系统。因为是从数据库中查找,locate的速度远远快于find命令。但是,使用locate命令查找的结果仅仅是在当前数据库。locate数据库是通过cron的日任务更新的,你也可以手工进行,使用“locate -u;updatedb”命令完成(通常需要root权限)。当我们建立好这个数据库后,就可以方便地搜寻所需文件了。
实例应用如下。
(1)建立数据库:
locate -u
(2)查找所有包含字符“kde”并且在目录bin中的文件:
locate kde | grep bin
2.2.20 rmdir:删除目录
格式:rmdir [选项]... 目录...
选项如下。
● --ignore-fail-on-non-empty:忽略任何因目录仍有数据而造成的错误。
● -p, --parents:删除指定目录后,若该目录的上层目录已变成空目录,则将其一并删除。
● -v, --verbose:显示指令执行过程。
● --help:显示此帮助信息并退出。
● --version:输出版本信息并退出。
说明:如果<目录>没有数据则删除该目录。rmdir所删除的目录,每级目录中都是空的,没有其他的文件。如果任何一级的目录有文件,也不能删除。
应用实例如下。
使用-p参数删除目录时是一级一级地施行的。
mkdir -p /sirdoc/redhat/
注意 首先在当前目录下创建目录sirdoc, sirdoc内又有一个子目录redhat。
# rmdir -p sirdoc/redhat/
注意,删除linuxsir目录,要用到参数-p。
2.2.21 basename:显示文件或者目录的基本名称
作用:显示文件或者目录的基本名称。
格式:basename名称 [后缀]
或:basename选项
去掉前导的目录部分后打印“名称”。
如果指定的话,还会去掉尾随的“后缀”。
● --help:显示此帮助信息并退出。
● --version:输出版本信息并退出。
应用实例如下。
(1)输出“sort”:
basename /usr/bin/sort
(2)输出“stdio”:
basename include/stdio.h .h
2.2.22 chattr:改变文件的属性
作用:chattr可以防止关键文件被修改。
格式:chattr [选项] 文件或目录
选项如下。
● -R:递归处理所有的文件及子目录。
● -V:详细显示修改内容,并打印输出。
● -:失效属性。
● +:激活属性。
● =:指定属性。
● A:Atime,告诉系统不要修改对这个文件的最后访问时间。
● S:Sync,一旦应用程序对这个文件执行了写操作,系统立刻把修改的结果写到磁盘。
● a:Append Only,系统只允许在这个文件之后追加数据,不允许任何进程覆盖或截断这个文件。
如果目录具有这个属性,系统将只允许在这个目录下建立和修改文件,而不允许删除任何文件。
● i:Immutable,系统不允许对这个文件进行任何修改。如果目录具有这个属性,那么任何进程只能修改目录下的文件,不允许建立和删除文件。
● D:检查压缩文件中的错误。
● d:No dump,在进行文件系统备份时,dump程序将忽略这个文件。
● C:Compress,系统以透明的方式压缩这个文件。从这个文件读取时,返回的是解压之后的数据;而向这个文件中写入数据时,数据首先被压缩,之后才写入磁盘。
● s:Secure Delete,让系统在删除这个文件时,使用0填充文件所在的区域。
● u:Undelete,当一个应用程序请求删除这个文件的,系统会保留其数据块,以便以后能够恢复删除这个文件。
说明:chattr命令的作用很大,其中一些功能是由Linux内核版本来支持的,如果Linux内核版本低于2.2,那么许多功能不能实现。同样-D检查压缩文件中的错误,需要2.5.19以上内核才能支持。另外,通过chattr命令修改属性能够提高系统的安全性,但是它并不适合所有的目录。chattr命令不能保护/、/dev、/tmp、/var目录。
应用实例如下。
(1)恢复/root目录,即子目录的所有文件。
# chattr -R +u/root
(2)用chattr命令防止系统中某个关键文件被修改。
在Linux下,有些配置文件(passwd,fatab)是不允许任何人修改的,为了防止被误删除或修改,可以设定该文件的“不可修改位(immutable)”,命令如下:
# chattr +i /etc/fstab
2.2.23 cksum:文件的CRC校验
作用:打印每个文件的CRC校验和及字节统计。
格式:cksum [文件]...
或:cksum [选项]
选项如下。
● --help:显示此帮助信息并退出。
● --version:输出版本信息并退出。
说明:CRC(Cyclic Redundancy Check,循环冗余校验码)是常用的校验码,在早期的通信中运用广泛,因为早期的通信技术不够可靠(不可靠性的来源是通信技术决定的,比如电磁波通信时受雷电等因素的影响),不可靠的通信就会带来“确认信息”的困惑,比如红军和蓝军通信联合进攻山下的敌军的例子:第一天红军发了一条信息要蓝军第二天一起进攻,蓝军收到之后,发一条确认信息,但是蓝军担心的是“确认信息”如果也不可靠而没有成功到达红军那里,那自己岂不是很危险?于是红军再发一条“对确认的确认信息”,但同样的问题还是不能解决,红军仍然不敢贸然行动。对通信的可靠性检查就需要“校验”,校验是从数据本身进行检查,它依靠某种数学上约定的形式进行检查,校验的结果是可靠或不可靠,如果可靠就对数据进行处理,如果不可靠,就丢弃重发或者进行修复。
CRC码由两部分组成,前半部分是信息码,就是需要校验的信息,后半部分是校验码,如果CRC码共长n个bit,信息码长k个bit,就称为(n,k)码。它的编码规则是:
(1)首先将原信息码(kbit)左移r位(k+r=n)
(2)运用一个生成多项式g(x)(也可看成二进制数)用模2除上面的式子,得到的余数就是校验码。
非常简单。要说明的是:模2除就是在除的过程中用模2加,模2加实际上就是我们熟悉的异或运算,就是加法不考虑进位,公式是:
0+0=1+1=0,1+0=0+1=1
即“异”则真,“非异”则假。
由此得到定理:
a+b+b=a
也就是“模2减”和“模2加”直值表完全相同。
有了加减法就可以用来定义模2除法,于是就可以用生成多项式g(x)生成CRC校验码。
例如:g(x)=x4+x3+x2+1,(7,3)码,信息码110产生的CRC码就是:
11101 | 110,0000(设a=11101,b=1100000)
取b的前5位11000跟a异或得到101,101加上b没有取到的00得到10100,然后跟a异或得到01001,也就是余数1001,余数是1001,所以CRC码是110,1001。
对于g(x)=x4+x3+x2+1的解释:(都是从右往左数)x4就是第五位是1,因为没有x1所以第2位就是0。
标准的CRC码是,CRC-CCITT和CRC-16,它们的生成多项式是:
CRC-CCITT=x16+x12+x5+1
CRC-16=x16+x15+x2+1
应用实例如下。
使用CRC检验文件:
cksum 1.txt 2422907486124 1.txt
2.2.24 cmp:比较文件差异
作用:比较文件差异。
格式:cmp [选项] [第1个文件][第2个文件]
选项如下。
● -c或--print-chars:除了标明差异处的十进制字码之外,一并显示该字符所对应字符。
● -i<字符数目>或--ignore-initial=<字符数目>:指定一个数目。
● -l或--verbose:标示出所有不一样的地方。
● -s或--quiet或--silent:不显示错误信息。
● -v或--version:显示版本信息。
● --help:在线帮助。
应用实例如下。
比较两个文本文件:
#cmp 1.txt redhat_pack.txt 1.txt redhat_pack.txt differ: byte 1, line 1
2.2.25 split:分割文件
作用:切割文件。
格式:split [选项] [INPUT [PREFIX]]
[INPUT]:前置文件名。
[选项]主要参数如下。
● -l:指定每多少行就要切成一个小文件。
● -c:与-b参数类似,但切割时尽量维持每行的完整性。
● -b:指定每多少字节就要切成一个小文件。b表示512字节,k表示1KB,m表示1MB。
[PREFIX]:设置切割后文件的前置文件名,split会自动在前置文件名后再加上编号。
实例应用如下。
把一个大文件file分割成1MB大小的文件:
Split -b 1m file filebak_
2.2.26 dirname:显示文件除名字外的路径
作用:显示文件除名字外的路径。
格式:dirname名称或:dirname选项
● --help:显示此帮助信息并退出。
● --version:输出版本信息并退出。
应用实例如下。
(1)查看/usr/bin/sort路径:
# dirname /usr/bin/sort /usr/bin
(2)查看stdio.h路径:
dirname stdio.h
2.2.27 find:查找目录或者文件
作用:寻找文件、目录。
使用权限:所有用户。
格式:find [path][选项][expression]
path指定目录路径,系统从这里开始沿着目录树向下查找文件。它是一个路径列表,相互用空格分离,如果不写path,那么默认为当前目录。
选项如下。
● -depth:使用深度级别的查找过程方式,在某层指定目录中优先查找文件内容。
● -maxdepth levels:表示至多查找到开始目录的第level层子目录。level是一个非负数,如果level是0,表示仅在当前目录中查找。
● -mindepth levels:表示至少查找到开始目录的第level层子目录。
● -mount:不在其他文件系统(如Msdos、Vfat等)的目录和文件中查找。
● -version:打印版本。
[expression]是匹配表达式,是find命令接受的表达式,find命令的所有操作都是针对表达式的。它的参数非常多,这里只介绍一些常用的参数。
● -name:支持通配符“*”和“?”。
● -atime n:搜索在过去n天读取过的文件。
● -ctime n:搜索在过去n天修改过的文件。
● -group grpoupname:搜索所有组为grpoupname的文件。
● -user用户名:搜索所有文件属主为用户名(ID;名称)的文件。
● -size n:搜索文件大小是n个block的文件。
● -print:输出搜索结果,并且打印。
实例应用如下。
find命令查找文件的5种方法如下。
(1)文件名查找
find / -name named.conf
(2)快速查找文件法
如果知道文件存放在某个目录中,那么只要在这个目录中往下寻找就能节省很多时间。比如named.conf文件,从它的文件后缀“.conf”可以判断这是一个配置文件,那么它应该在/etc目录内,此时可以使用下面命令:
find /etc -name named.conf
(3)根据部分文件名查找法
有时知道仅某个文件包含有abdd这4个字符,那么要查找系统中所有包含这4个字符的文件可以输入下面命令:
find / -name '*abdd*'
输入这个命令以后,Linux系统将会在“/”目录中查找所有包含abdd这4个字符的文件(其中“*”是通配符),比如,abddrmyz等符合条件的文件都能显示出来。
(4)根据文件的特征查询法
有时知道某个文件的大小、修改日期、所属用户等特征,也可以使用“find”命令查找出文件来,例如,查找在系统中属于已经作废用户的文件,可以使用命令:
find / -nouser
(5)混合查找方式查找法
find命令可以使用混合查找的方法。例如,我们想在“/home”目录中查找大于500000字节,并且属于cao用户的文件,则可以使用-and(与)把两个查找参数连接起来组合成一个混合的查找方式。
find /home -size +500000c -and -user cao
2.2.28 findfs:通过列表或用户ID查找文件系统
作用:findfs命令用来查找指定卷标的文件系统。
格式:
findfs LABEL=<label> findfs UUID=<uuid>
主要选项如下。
LABEL=<label>:卷标名称。
UUID=<uuid>:分区的UUID号。
说明:随着Linux系统中硬盘容量和数目的增加,Linux系统中分区数量也越来越多,使用findfs命令可以通过卷标名称或UUID号快速定位分区位置。
应用实例如下。
查找卷标名称是“/var/ftp”的分区位置,使用命令:
#findfs LABEL=/var/ftp /dev/hda9
2.2.29 ln:链接文件或目录
作用:链接文件或目录。
格式:ln [选项][源文件或目录][目标文件或目录]
或:ln [选项][源文件或目录...][目的目录]
选项如下。
● -b或--backup:删除,覆盖目标文件之前的备份。
● -d或-F或--directory:建立目录的硬连接。
● -f或--force:强行建立文件或目录的连接,不论文件或目录是否存在。
● -i或--interactive:覆盖既有文件之前先询问用户。
● -n或--no-dereference:把符号链接的目的目录视为一般文件。
● -s或--symbolic:对源文件建立符号链接,而非硬链接。
● -S<字尾备份字符串>或--suffix=<字尾备份字符串>:用“-b”参数备份目标文件后,备份文件的字尾会被加上一个备份字符串,预设的字尾备份字符串是符号“~”,你可通过“-S”参数来改变它。
● -v或--verbose:显示指令执行过程。
● -V<备份方式>或--version-control=<备份方式>:用“-b”参数备份目标文件后,备份文件的字尾会被加上一个备份字符串,这个字符串不仅可用“-S”参数变更,当使用“-V”参数<备份方式>指定不同备份方式时,也会产生不同字尾的备份字符串。
● --help:在线帮助。
● --version:显示版本信息。
说明:ln指令用于链接文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则会把前面指定的所有文件或目录复制到该目录中。若同时指定多个文件或目录,且最后的目的地并非是一个已存在的目录,则会出现错误信息。
链接有两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link)。建立硬链接时,链接文件和被链接文件必须位于同一个文件系统中,并且不能建立指向目录的硬链接。而对于符号链接,则不存在这个问题。默认情况下,ln产生硬链接。
在硬链接的情况下,参数中的“目标”被链接至[链接名]。如果[链接名]是一个目录名,系统将在该目录之下建立一个或多个与“目标”同名的链接文件,链接文件和被链接文件的内容完全相同。如果[链接名]为一个文件,用户将被告知该文件已存在且不进行链接。如果指定了多个“目标”参数,那么最后一个参数必须为目录。
应用实例如下。
(1)用户为当前目录下的文件lunch创建了一个符号链接/home/xu:
$ ln - s lunch /home/xu
说明: 给ln命令加上-s选项,则建立符号链接。如果[链接名]已经存在但不是目录,将不做链接。[链接名]可以是任何一个文件名(可包含路径),也可以是一个目录,并且允许它与“目标”不在同一个文件系统中。如果[链接名]是一个已经存在的目录,系统将在该目录下建立一个或多个与“目标”同名的文件,此新建的文件实际上是指向原“目标”的符号链接文件。
(2)创建到一个文件的另一个链接,请输入:
#ln -f chap1 intro
这会将chap1链接到新的名称,intro。如果intro不存在,那么会创建该文件名。如果intro已经存在了,那么这个文件会被替换为指向chap1的一个链接。然后chap1和intro文件名会指向同一个文件。对在这里面任何一个的更改都会出现在另一个中。如果一个文件名被rm命令删除,那么该文件并没有完全被删除,因为它依旧以其他名字存在。
(3)将文件链接为另一个目录中的相同名字,请输入:
#ln index manual
这会将index链接到新名称,manual/index。
(4)将几个文件链接为另一个目录中的名称,请输入:
ln chap2 jim/chap3 /home/manual
这会将chap2链接到新名称/home/manual/chap2;将jim/chap3链接到新名称/home/manual/chap3。
(5)要在不指明目标文件参数的情况下得到相同的结果,请输入:
ln -s /tmp/toc
2.2.30 lndir:链接目录内容
作用:链接目录内容。
格式:lndir [-ignorelinks][-silent][源目录][目的目录]
● -ignorelinks:直接建立符号链接的符号链接。
● -silent:不显示指令执行过程。
说明:执行lndir指令,可一口气把源目录下的文件和子目录统统建立起相互对应的符号链接。
2.2.31 lsattr:显示文件属性
作用:改变文件属性。
格式:chattr [选项][+/-/=<属性>][文件或目录...]
选项如下。
● -R:递归处理,将指定目录下的所有文件及子目录一并处理。
● -v<版本编号>:设置文件或目录版本。
● -V:显示指令执行过程。
● +<属性>:开启文件或目录的该项属性。
● -<属性>:关闭文件或目录的该项属性。
● =<属性>:指定文件或目录的该项属性。
说明:这项指令可改变存放在ext2、ext3文件系统上的文件或目录属性。
这些属性共有以下8种模式。
● a:让文件或目录仅供附加用途。
● b:不更新文件或目录的最后存取时间。
● c:将文件或目录压缩后存放。
● d:将文件或目录排除在倾倒操作之外。
● i:不得任意更动文件或目录。
● s:保密性删除文件或目录。
● S:即时更新文件或目录。
● u:预防意外删除。
2.2.32 od:输出文件内容
作用:od指令会读取所给予的文件的内容,并将其内容以八进制字码呈现出来。
格式:od [选项]...[文件]...
选项如下。
● -a:此参数的效果和同时指定“-ta”参数相同。
● -A<字码基数>:选择要以何种基数计算字码。
● -b:此参数的效果和同时指定“-toC”参数相同。
● -c:此参数的效果和同时指定“-tC”参数相同。
● -d:此参数的效果和同时指定“-tu2”参数相同。
● -f:此参数的效果和同时指定“-tfF”参数相同。
● -h:此参数的效果和同时指定“-tx2”参数相同。
● -i:此参数的效果和同时指定“-td2”参数相同。
● -j<字符数目>或--skip-bytes=<字符数目>:略过设置的字符数目。
● -l:此参数的效果和同时指定“-td4”参数相同。
● -N<字符数目>或--read-bytes=<字符数目>:到设置的字符数目为止。
● -o:此参数的效果和同时指定“-to2”参数相同。
● -s<字符串字符数>或--strings=<字符串字符数>:只显示符合指定的字符数目的字符串。
● -t<输出格式>或--format=<输出格式>:设置输出格式。
● -v或--output-duplicates:输出时不省略重复的数据。
● -w<每列字符数>或--width=<每列字符数>:设置每列的最大字符数。
● -x:此参数的效果和同时指定“-h”参数相同。
● --help:在线帮助。
● --version:显示版本信息。
应用实例如下。
显示txt文件八进制码:
# od 1.txt 0000000072560066142061551061440060554071563044040066145 0000020067554075440005012072560066142061551044040066145 0000040067554024450075440076412005012072560066142061551 0000060071440060564064564020143067566062151066440064541 0000100024156072123064562063556056533060440063562024563 0000120075440051412071571062564027155072557027164071160 0000140067151066164024156044042066145067554053440071157 0000160062154021041035451076412005012005175 0000174
2.2.33 paste:合并文件的列
作用:paste指令会把每个文件以列对列的方式,一列列地加以合并。
格式:paste [选项]...[文件]...
● -d<间隔字符>或--delimiters=<间隔字符>:用指定的间隔字符取代跳格字符。
● -s或--serial:串列进行而非平行处理。
● --help:在线帮助。
● --version:显示帮助信息。
应用实例如下。
显示txt文件:
# paste 1.txt public class Hello { public Hello() { } public static void main(String[] args) { System.out.println("Hello World! "); } }
2.2.34 stat:显示inode内容
作用:stat以文字的格式来显示inode的内容。
格式:stat [文件或目录]
应用实例如下。
查看txt文件的inode内容:
# stat 1.txt File: “1.txt” Size: 0 Blocks: 0 IO Block: 4096 一般空文件 Device: fd00h/64768d Inode: 1182306 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2008-08-02 20:11:28.000000000 +0800 Modify: 2008-08-02 20:11:27.000000000 +0800 Change: 2008-08-02 20:11:27.000000000 +0800
说明:inode译成中文就是索引节点。每个存储设备或存储设备的分区(存储设备是硬盘、软盘、U盘……)被格式化为文件系统后,应该有两部分,一部分是inode,另一部分是Block。Block是用来存储数据用的。而inode用来存储这些数据的信息,包括文件大小、属主、归属的用户组、读写权限等。inode为每个文件进行信息索引,所以就有了inode的数值。操作系统根据指令,能通过inode值最快地找到相对应的文件。
2.2.35 tee:读取标准输入到标准输出并可保存为文件
作用:读取标准输入的数据,并将其内容输出成文件。
格式:tee [选项][文件...]
选项如下。
● -a或--append:附加到既有文件的后面,而非覆盖它。
● -i-i或--ignore-interrupts:忽略中断信号。
● --help:在线帮助。
● --version:显示版本信息。
说明:tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
应用实例如下。
(1)要同时查看和保存一个命令的输出:
#sort program.c | tee program.lint
它在工作站上显示命令sort program.c的标准输出,同时在文件program.lint中保存输出的一个副本。如果program.lint文件早已存在,它将被删除并替换。
(2)要同时查看一个命令的输出并保存到一个现有文件:
# sort program.c | tee -a program.lint
它将在工作站上显示sort program.c命令的标准输出,同时在program.lint文件尾部添加输出的一个副本。如果program.lint文件不存在,它将被创建。
2.2.36 tmpwatch:删除临时文件
作用:执行tmpwatch指令可删除不必要的暂存文件,你可以设置文件超期时间,单位以小时计算。
格式:tmpwatch [选项][超期时间][目录...]
选项如下。
● -a或--all:删除任何类型的文件。
● -f或--force:强制删除文件或目录,其效果类似于rm指令的“-f”参数。
● -q或--quiet:不显示指令执行过程。
● -v或--verbose:详细显示指令执行过程。
● -test:仅作测试,并不真地删除文件或目录。
2.2.37 touch:更新文件或目录时间
作用:修改文件时间信息。
格式:touch [选项]…[目录]…
选项如下。
● -a:改变文件的读取时间记录。
● -c, --no-create:不建立任何文件。
● -d, --date=STRING:设定时间与日期,可以使用各种不同的格式。
● -F SEC, --forward=SEC:使用参考文件的时间记录。
● -m:改变文件的修改时间记录。
● -r, --reference=文件:使用指定文件的时间属性而非目前的时间。
● -t STAMP:使用 [[CC]YY]MMDDhhmm[.ss] 格式的时间而非目前的时间。
实例应用如下。
(1)将文件的时间记录改为现在的时间。若文件不存在,系统会建立一个新的文件。
touch myfile
(2)将文件myfile的时间记录改为1月6日18点3分。时间的格式可以参考date指令,至少需输入MMDDhhmm,就是月、日、时与分。
touch -c -t 01061803 myfile
(3)将myfile的时间记录改成1月6日18点3分,公元2005年。时间可以使用am,pm,是24小时的格式,日期可以使用其他格式如6 JAN 2005。
touch -d "6:03pm 01/06/2005" file
(4)应用进阶
有时Linux文件系统空间被占满了,要查询滥用磁盘的用户。首先要查出哪些文件是新创建的,哪些是更新的,以便找出不正常的大文件。使用命令touch生成一个文件,时间戳会根据情况设定为比较近的日期,再使用find命令找出更新的文件:
touch -d "6:03pm 02/06/2005" test find /home -newer test –print
系统会在屏幕上显示那些更新的文件的位置,也就知道了它的用户。
2.2.38 tree:以树状图显示目录内容
作用:有时候我们想了解一个文件夹或者驱动器根目录下的所有文件,并希望它以资源管理器的树形视图方式显示文件结构。
格式:tree [选项][目录...]
选项如下。
● -a:显示所有文件和目录。
● -A:使用ASNI绘图字符显示树状图而非以ASCII字符组合。
● -C:给文件和目录清单加上色彩,便于区分各种类型。
● -d:显示目录名称而非内容。
● -D:列出文件或目录的更改时间。
● -f:在每个文件或目录之前,显示完整的相对路径名称。
● -F:在执行文件,目录,Socket,符号链接,管道名称名称,各自加上“*”,“/”,“=”,“@”,“|”号。
● -g:列出文件或目录的所属群组名称,没有对应的名称时,则显示群组识别码。
● -i:不以阶梯状列出文件或目录名称。
● -I<范本样式>:不显示符合范本样式的文件或目录名称。
● -l:如遇到性质为符号链接的目录,直接列出该连接所指向的原始目录。
● -n:不给文件和目录清单加上色彩。
● -N:直接列出文件和目录名称,包括控制字符。
● -p:列出权限标示。
● -P<范本样式>:只显示符合范本样式的文件或目录名称。
● -q:用“?”号取代控制字符,列出文件和目录名称。
● -s:列出文件或目录大小。
● -t:按文件和目录的更改时间排序。
● -u:列出文件或目录的拥有者名称,没有对应的名称时,则显示用户识别码。
● -x:将范围局限在现行的文件系统中,若指定目录下的某些子目录,其存放于另一个文件系统上,则将该子目录排除在寻找范围外。
应用实例如下。
查看/root/ossec-hids-1.5目录树结构,分页显示:
# tree /root/ossec-hids-1.5 |more /root/ossec-hids-1.5 |-- BUGS |-- CONFIG |-- CONTRIB |-- INSTALL |-- LICENSE |-- README |-- active-response | |-- disable-account.sh | |-- firewall-drop.sh | |-- firewalls | | |-- ipfw.sh | | |-- ipfw_mac.sh | | `-- pf.sh | |-- host-deny.sh | `-- route-null.sh
2.2.39 umask:指定在建立文件时预设的权限掩码
作用:指定在建立文件时预设的权限掩码。
格式:umask [-p] [-S] [mode]
选项如下。
● -S:以文字的方式来表示权限掩码。
● -p:以数字的方式来表示权限掩码。
● mode:权限掩码。
说明:当最初登录到系统中时,umask命令确定了创建文件的默认模式。这一命令实际上和chmod命令正好相反。系统管理员必须要为你设置一个合理的umask值,以确保你创建的文件具有所希望的默认权限,防止其他非同组用户对你的文件具有写权限。在已经登录之后,可以按照个人的偏好使用umask命令来改变文件创建的默认权限。相应的改变直到退出该shell或使用另外的umask命令之前一直有效。一般来说,umask命令是在/etc/profile文件中设置的,每个用户在登录时都会引用这个文件,所以如果希望改变所有用户的umask,可以在该文件中加入相应的条目。如果希望永久性地设置自己的umask值,那么就把它放在自己$HOME目录下的.profile或.bash_profile文件中。
关于如何计算umask值,umask命令允许你设定文件创建时的默认模式,对应每一类用户(文件属主、同组用户、其他用户)存在一个相应的umask值中的数字。对于文件来说,这一数字的最大值是6。系统不允许你在创建一个文本文件时就赋予它执行权限,必须在创建后用chmod命令增加这一权限。目录则允许设置执行权限,这样针对目录来说,umask中各个数字最大可以到7。
表2-3列出了常用的umask值及对应的目录和文件权限。
表2-3 常用的umask值及对应的目录和文件权限
实例应用如下。
(1)如果想知道当前的umask值,可以使用没有任何参数的umask命令:
#umask 0022
(2)如果想要改变umask值,只要使用umask命令设置一个新的值即可:
#umask 002
(3)确认一下系统是否已经接受了新的umask值:
# umask 002 # umask 0002
在使用umask命令之前,一定要弄清楚到底希望文件/目录具有什么样的默认权限。否则可能会得到一些非常奇怪的结果。例如,如果将umask值设置为600,那么所创建的文件/目录的默认权限就是066。
(4)使用umask设置安全权限:
# umask 117 # umask -S u=rw,g=rw,o=
上述命令把umask值改为177,结果只有文件所有者具有读写文件的权限,其他用户不能访问该文件。这显然是一种非常安全的状态。
2.2.40 chmod:设置文件或者目录的权限
作用:chmod是change file or directory' s mode的缩写,作用是修改文件、目录的访问权限,用户可以用它控制文件、目录的访问权限。
格式:chmod命令有两种用法。一种是包含字母和操作符表达式的字符设定法(相对权限设定);另一种是包含数字的数字设定法(绝对权限设定)。
(1)字符设定法
chmod [ugoa] [+ | - | =] [rwxXstugo] 文件名
第一部分决定权限的授予者,第二部分决定对权限进行何种操作(添加、删除、设定),第三部分决定具体要授予的权限,三部分组成一个字符串,也就是mode参数值。详细描述如表2-4所示。
表2-4 chmod字符设定模式的用法
实例应用如下。
如果一个系统管理员写了一个通知(news)让所有用户阅读,那么必须授权用户对这个文件有读权限,可以使用命令:
#chmod a=r news
(2)数字设定法
数字设定法的一般形式为:chmod [mode] 文件名
数字属性的格式应为3个0~7的八进制数,其顺序是(u)(g)(o)文件名,以空格分开要改变权限的文件列表,支持通配符。
数字表示的权限的含义如下:
● 0001:所有者的执行权限。
● 0002:所有者的写权限。
● 0004:所有者的读权限。
● 0010:组的执行权限。
● 0020:组的写权限。
● 0040:组的读权限。
● 0100:其他人的执行权限。
● 0200:其他人的写权限。
● 0400:其他人的读权限。
● 1000:粘贴位置位。
● 2000:假如这个文件是可执行文件,则为组ID位置位,否则其中文件锁定位置位。
● 4000:假如这个文件是可执行文件,则为用户ID位置位。
● 系统管理员写了一个通知(news)让所有用户阅读,那么必须授权用户对这个文件有读权限,可以使用命令:
#chmod 444 news2
上述命令中,数字444是如何计算出来的呢?0004为所有者的读权限,0040为组的读权限,0400为其他人的读权限,这3个数字相加就是0444(以上数字都是八进制数),如图2-8所示。
图2-8 分别用字符设定法和数字设定法修改文件权限
从图2-8中可以看到“chmod 444 news”和“chmod a=r news”命令是等价的。
说明:因为Linux系统有能力支持多用户,在每一方面系统都会做出谁能读、写和执行的资源权力限制。这个权限以三个八位元的方式存储着,一个表示文件所属者,一个表示文件所属群组,一个表示其他人。这些数字以下列方式表示,如表2-5所示。
表2-5 权限的表示形式
2.2.41 chgrp:改变文件或者目录所属的群组
作用:chgrp是change file or directory's owner的缩写,用于修改一个或多个文件、目录所属的组。
格式:chgrp [选项]…组 文件…
或chgrp [选项]…--reference=参考文件 文件…
将每个<文件>的所属组设定为<组>。
选项如下。
● -c, --changes:类似--verbose选项,只在有更改时才显示结果。
● --dereference:影响符号链接所指示的对象,而非符号链接本身。
● -h, --no-dereference:影响符号链接本身,而非符号链接所指示的目的地(当系统支持更改符号链接的所有者时,此选项才有效)。
● -f, --silent:不显示错误信息。
● --reference=参考文件:使用<参考文件>的所属组,而非指定的<组>。
● -R, --recursive:递归处理所有的文件及子目录。
● -v, --verbose:显示命令执行过程。
说明:该命令改变指定文件所属的用户组。其中group可以是用户组ID,也可以是/etc/group文件中用户组的组名。文件名是以空格分开的要改变所属组的文件列表,支持通配符。如果用户不是该文件的属主、超级用户,则不能改变该文件的组。
实例应用如下。
将目录dir的所有文件属组改为sam:
# chgrp -R sam dir/
2.2.42 chown:改变文件的拥有者或者群组
作用:chown是change file or directory's group的缩写,用于更改一个或多个 <文件> 的 <所有者> 及/或 <所属组>。
使用权限:超级用户。
格式:
chown [选项]…所有者[:[组]] 文件…
或chown [选项]…:组 文件…
或chown [选项]…--reference=参考文件 文件…
选项如下。
● --dereference:影响符号链接所指示的对象,而非符号链接本身。
● -h, --no-dereference:影响符号链接本身,而非符号链接所指示的目的地(当系统支持更改符号链接的所有者时,此选项才有效)。
● --from=目前所有者:目前组,只当每个文件的所有者和组符合选项所指定的时,才会更改所有者和组。其中一个可以省略,这个已省略的属性就不需要符合原有的属性。
● -f, --silent:不显示错误信息。
● -R, --recursive:递归处理所有的文件及子目录。
● -v, --verbose:处理任何文件都会显示信息。
说明:chown将指定文件的拥有者改为指定的用户或组,用户可以是用户名或用户ID;组可以是组名或组ID;文件是以空格分开的要改变权限的文件列表,支持通配符。系统管理员经常使用chown命令,在将文件复制到另一个用户的目录下以后,让用户拥有使用该文件的权限。
实例应用如下。
把目录/mywork及其下的所有文件和子目录的属主改成lwan,属组改成users:
# chown - R lwan.users /mywork
2.3 小结
文件系统是Linux系统的基础,Linux应用程序、库文件、系统文件和用户文件都驻留在文件系统上,因此全面掌握Linux文件系统是很重要的。在Linux系统中,所有内容被表示为文件,组织文件的各种方法便称为不同的文件系统。Linux支持多种文件系统,使之能够与不同的操作环境实现资源共享,这也是Linux作为网络操作系统的明显优势。