Red Hat Linux 9实务自学手册
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第5章 文件系统管理

文件以及磁盘管理是Linux系统中两个非常重要的模块。本章将对Linux文件系统的管理以及文件与目录操作的一些重要命令、Linux下的磁盘管理等做详细的介绍。

5.1 了解Linux文件系统(实务11)

Linux文件系统是Linux系统的核心模块。通过使用文件系统,用户可以很好地管理各项文件及目录资源。本节将对Linux常用的文件系统、文件的基本概念和目录的基本概念等进行系统、全面的介绍。

5.1.1 了解Linux常用的文件系统

随着Linux的不断发展,其所能支持的文件格式系统也在迅速扩充。特别是Linux2.4内核正式推出后,出现了大量新的文件系统,其中包括日志文件系统Ext3、ReiserFS、XFS、JFS和其他文件系统。Linux系统核心可以支持十多种文件系统类型:JFS、ReiserFS、Ext、Ext2、Ext3、ISO9660、XFS、Minx、MSDOS、UMSDOS、VFAT、NTFS、HPFS、NFS、SMB、SysV、PROC等。其中,较为普遍的有如下几种。

● - Minix是Linux支持的第一个文件系统,对用户有很多限制,性能低下,有些没有时间标记,文件名最长l4个字符。Minix文件系统最大的缺点是只能使用64MB的硬盘分区,所以目前已经没有人使用该文件系统了。

● - Xia是Minix文件系统修正后的版本,在一定程度上解决了文件名和文件系统大小的局限;但没有新的特色,目前很少有人使用。

● - ISO9660标准CDROM文件系统,通用的Rock Ridge增强系统,允许长文件名。

● - NFS(Network File System)是Sun公司推出的网络文件系统,允许在多台计算机之间共享同一文件系统,易于从所有这些计算机上存取文件。

● - SysV是System V/Coherent在Linux平台上的文件系统。

● - 扩展文件系统(Ext File System)是随着Linux不断地成熟而引入的,它包含了几个重要的扩展,但提供的性能不令人满意。1994年人们引入了第二扩展文件系统(second Extended Filesystem,Ext2);

● - Ext3(third Extended Filesystem)是由开放资源社区开发的日志文件系统,被设计成Ext2的升级版本,尽可能地方便用户从Ext2向Ext3迁移。Ext3在Ext2的基础上加入了记录元数据的日志功能,努力保持向前和向后的兼容性。这个文件系统也许称为Ext2的下一个版本更为合适些。Ext3还支持异步的日志,这意味着其性能可能比Ext2还好。

除了上面这些Linux文件系统外,Linux还可以支持基于Windows和Netware的文件系统,例如UMSDOS、MSDOS、VFAT、HPFS、SMB和NCPFS等。兼容这些文件系统对Linux用户来说也是很重要的,毕竟在桌面环境下Windows文件系统还是很流行的,而Netware网络也有许多用户,Linux用户也要共享这些文件系统的数据。

● - UMSDOS是一种Linux下的MSDOS文件系统驱动,支持长文件名、所有者、允许权限、连接和设备文件。允许一个普通的MSDOS文件系统用于Linux,而且无须为其建立单独的分区。

● - MSDOS是在DOS、Windows和某些OS/2操作系统上使用的一种文件系统,其名称采用“8+3”的形式,即8个字符的文件名加上3个字符的扩展名。

● - VFAT是在Windows 9X和Windows 2000下使用的一种DOS文件系统,其在DOS文件系统的基础上增加了对长文件名的支持。

● - HPFT——高性能文件系统(High Performance File System,HPFS)是微软LAN Manager中的文件系统,同时也是IBM的LAN Server和OS/2的文件系统。HPFT能访问较大的硬盘驱动器,提供了更多的组织特性,并改善了文件系统的安全特性。

● - SMB是一种支持Windows for Workgroups、Windows NT和Lan Manager的基于SMB协议的网络操作系统。

● - NCPFS是一种Novell NetWare使用NCP协议的网络操作系统。

● - NTFS是由Windows 2000/XP/2003操作系统支持、一个特别为网络和磁盘配额、文件加密等安全特性设计的磁盘格式。

5.1.2 了解Linux文件

本节详细介绍Linux文件系统中文件的定义、文件名的规定以及文件的类型。

1.文件与文件名

在多数操作系统中都有文件的概念。在Linux中文件是存储信息的基本结构,是被命名(称为文件名)的存储在某种介质(如磁盘、光盘和磁带等)上的一组信息的集合。Linux文件均为无结构的字符流形式。文件名是文件的标识,它由字母、数字、下画线和圆点组成的字符串构成。用户应该尽量选择有意义的文件名,以方便识别和记忆。注意

注意

Linux要求文件名的长度限制在255个字符以内。

为了便于管理和识别,用户可以把扩展名作为文件名的一部分。圆点用于区分文件名和扩展名。扩展名对文件分类是十分有用的。用户可能对某些大众已接纳的标准扩展名比较熟悉。例如,用C++语言编写的源代码文件总是具有cpp的扩展名。用户可以根据自己的需要,随意加入自己的文件扩展名。以下例子给出一些有效的Linux文件名:

      HelloLinux              //不带扩展名的文件
      Squid.conf              //文本文件
      Install.pl              //perl脚本文件

2.文件的类型

Linux系统中有三种基本的文件类型:普通文件、目录文件和设备文件。

(1)普通文件:是用户最经常使用和熟悉的文件,它又分为文本文件和二进制文件两种。

● - 文本文件:这类文件以文本的ASCII码形式存储在计算机中,是以“行”为基本结构的一种信息组织和存储方式。

● - 二进制文件:这类文件以文本的二进制形式存储在计算机中。用户一般不能直接读懂它们,只有通过相应的软件才能将其显示出来。二进制文件一般是可执行的程序、图形、图像、声音等。

(2)目录文件:主要目的是用于管理和组织系统中的大量文件,其存储一组相关文件的位置、大小等与文件有关的信息。目录文件一般简称为目录。

(3)设备文件:Linux系统把每一个I/O设备都看成一个文件(这点与Windows系列操作系统有很大区别),与普通文件一样处理,这样可以使文件与设备的操作尽可能统一。从用户的角度来看,对I/O设备的使用和一般文件的使用一样,不必了解I/O设备的细节。设备文件可以细分为块设备文件和字符设备文件。前者的存取是以字符块为单位的,后者则以单个字符为单位。

5.1.3 了解Linux目录

本节详细介绍Linux系统中的树形目录结构、工作目录、用户主目录等重要概念。

1.树形目录结构

在计算机系统中存有大量的文件,如何有效地组织与管理它们,并为用户提供一个使用方便的接口是文件系统的主要任务。Linux系统以文件目录的方式来组织和管理系统中的所有文件。所谓文件目录就是将所有文件的说明信息采用树形结构组织起来。整个文件系统有一个“根”(root),然后在根上分“杈”(directory),任何一个分杈上都可以再分杈,杈上也可以长出“叶子”。“根”和“杈”在Linux中被称为“目录”或“文件夹”。而“叶子”则是文件。实践证明,此种结构的文件系统效率高,现代操作系统基本上都采用这种结构方式。

如前所述,目录也是一种文件的类型。Linux系统通过目录将系统中所有的文件分级、分层组织在一起,形成了Linux文件系统的树形层次结构。以根目录为起点,所有其他的目录都由根目录派生而来,用户可以浏览整个系统,可以进入任何一个已授权进入的目录,从而访问其中的文件。

实际上,各个目录节点之下都会有一些文件和子目录。并且,系统在建立每一个目录时,都会自动为它设定两个目录文件,一个是“.”,代表该目录自己;另一个则是“..”,代表该目录的父目录。

注意

对于根目录,“.”和“..”都代表其自身。

Linux目录提供了管理文件的一个方便途径。每个目录都包含文件。用户可以为自己的文件创建自己的目录,也可以把一个目录下的文件移动或复制到另一个目录下,而且能移动整个目录,与系统中的其他用户共享目录和文件。也就是说,用户能够方便地从一个目录切换到另一个目录,而且可以设置目录和文件的管理权限,以便允许或拒绝其他人对其进行访问。同时,文件目录结构的相互关联性使共享数据变得十分容易,几个用户可以访问同一个文件,因此允许用户设置文件的共享程度。

注意

根目录(系统目录)是Linux系统中的特殊目录。Linux是一个多用户系统,操作系统本身的驻留程序存放在以根目录开始的专用目录中。

2.工作目录与用户主目录

从逻辑上讲,用户登录Linux系统之后,每时每刻都处在某个目录之中,此目录被称为工作目录或当前目录(Working Directory)。工作目录是可以随时改变的。用户初始登录到系统中时,其主目录(Home Directory)就成为其工作目录。工作目录用“.”表示,其父目录用“..”表示。

用户主目录是系统管理员在增加用户时建立起来的(以后也可以根据实际情况改变),每个用户都有自己的主目录,不同用户的主目录一般互不相同。用户刚登录到系统中时,其工作目录便是该用户的主目录,通常与用户的登录名相同。用户可以通过一个“~”符来引用自己的主目录。

举个例子,假设用户liyang的主目录为/home/liyang,那么如下的cat文件显示命令中所采用的两条路径就完全是一样的,因而其运行结果是相同的:

      #cat ~/own/softwares
      #cat /home/liyang/own/softwares

3.路径

对文件进行访问时,要用到“路径”的概念。顾名思义,路径是指从树形目录中的某个目录层次到某个文件的一条道路。此路径的主要构成是目录名称,中间用“/”隔开。任何一个文件在文件系统中的位置都是由相应的路径决定的。

用户在对文件进行访问时,要给出文件所在的路径。路径又分相对路径和绝对路径两种。绝对路径是指从“根”开始的路径,也称为完全路径;相对路径是从用户工作目录开始的路径。

注意

在树形目录结构中到某一确定文件的绝对路径和相对路径均只有一条。绝对路径是确定不变的,而相对路径则随着用户工作目录的变化而变化。

用户要访问一个文件时,可以通过路径名来引用。并且为了操作方便起见,完全可以根据要访问的文件与用户工作目录的相对位置来引用它,而不需要列出这个文件完整的路径名。例如,用户liyang有一个名为program的目录,该目录中有两个文件:time.conf和test.java。若用户liyang想显示出其program目录中的名为time.conf的文件,可以使用下列以绝对路径为基准的命令:

      //使用绝对路径访问
      #cat /home/liyang/program/time.conf

同样,如果用户已经切换到其主目录,那么此时也可以根据文件time.conf与当前工作目录的相对位置来引用该文件。这时命令为:

      //切换到用户主目录
      #cd /home/liyang
      //使用相对路径访问
      #cat program/time.conf

5.1.4 Linux系统的目录层次结构

Linux系统的目录层次结构比较复杂,下面将对其进行介绍。

● - /:根目录。在Windows,DOS或者其他类似的操作系统中,每个分区都会有一个相应的根目录。但是Linux和其他UNIX系统则把所有的文件都放在一个目录树里面,/就是唯一的根目录。一般来讲,根目录下面很少保存什么文件,或者只有一个内核映像在这里。

● - /boot:很多Linux系统把内核映像和其他一些和启动有关的文件都放在这里。

● - /tmp:一般只有启动时产生的临时文件才会放在这里。我们自己的临时文件都放在/var/tmp。

● - /mnt:这个目录下放着一些用来安装其他设备的子目录,比如说/mnt/cdrom或者/mnt/floppy。在有些Linux中这个目录是被/mount代替的。

● - /lib:启动的时候所要用到的库文件都放在这个目录下。那些非启动用的库文件都会放在/usr/lib下。内核模块是被放在/lib/modules/(内核版本)下的。

● - /proc:其实这个目录在磁盘上是不存在的。里面的文件都是关于当前系统的状态,包括正在运行的进程、硬件状态、使用多少内存等。

● - /dev:这个目录下保存着所有的设备文件。里面有一些由Linux内核创建的用来控制硬件设备的特殊文件。

● - /var:这里有一些被系统改变过的数据。比如说/var/tmp,就是用来储存临时文件的。还有很多其他的进程和模块把它们的记录文件也放在这个地方,包括如下一些重要的子目录:

/var/log:这里放着绝大部分的记录文件。随着时间的增长,这个目录会变得很庞大,所以要定期清理;

/var/run:包括了各种运行时的信息;

/var/lib:包括了一些系统运行时需要的文件;

/var/spool:邮件,新闻,打印序列的所在地。

● - /root:root用户的主目录。

● - /home:一般用户的主目录都会放在这个目录下。在Linux下,可以通过#cd ~ 来进入自己的主目录。

● - /etc:这里保存着绝大部分的系统配置文件。相对来讲,单个用户的系统配置文件会保存在这个用户自己的主目录里面。下面列举其中一些重要的子目录:

/etc/X11:这里放着X Window系统(Linux中的图形用户界面系统)所需要的配置文件。XF86Config就是把配置储存到这个地方的。/etc/X11/fonts里面放着一些服务器需要的字体,还存放一些窗口管理器存放的配置文件;

/etc/init.d:这个目录保存着启动描述文件,包括各种模块和服务的加载描述。所以如果不清楚的话,千万不要随便删除其中的文件,这里存放的文件都是系统自动进行配置的,不需要用户配置;

/etc/rcS.d:这里放着一些链接到/etc/init.d的文件,根据runlevel的不同而执行相应的描述。这里的文件名都是由S开头的,然后是一个两位的数字——表示各种服务启动的顺序。比如,S24foo就是在S42bar前面执行的。接着就是相应的链接到/etc/init.d下面的文件的名字了;

/etc/rc0.d - /etc/rc6.d:这里面也是一些链接文件,和/etc/rcS.d差不多。不同的是,这些只会在指定的runlevel下运行相应的描述。0表示关机,6表示重启。所有以K开头的文件表示关闭,所有以S开头的文件表示重启。目前,文件的命名方式和/etc/rcS.d是一样的。

● /bin,/sbin:这里分别放着启动时所需要的普通程序和系统程序。很多程序在启动以后也很有用,它们放在这个目录下是因为它们经常被其他程序调用。

● /usr:这是一个很复杂、庞大的目录。除了上述目录之外,几乎所有的文件都存放在这下面。下面列举其中一些重要的子目录:

/usr/X11R6,/usr/X11,/usr/Xfree86:这里保存着X Window系统所需要的文件,它的目录结构和/usr是一样的;

/usr/bin:二进制可执行文件存放的目录,这里放着绝大部分的应用程序;

/usr/sbin:这里放着绝大部分的系统程序;

/usr/games:游戏程序和相应的数据会放在这里;

/usr/include:这个目录保存着C和C++的头文件;

/usr/lib:启动时不用的库文件都会放在这里;

/usr/info:这里保存着GNU Info程序所需要的数据;

/usr/man:这里保存着man程序所需要的数据;

/usr/src:这里保存着源代码文件;

/usr/doc:这里保存着各种文档文件。这些文件可以帮助你了解Linux,解决问题和提供一些技巧;

/usr/local:这里面保存着本地计算机所需要的文件。在用户进行远程访问的时候特别有意义。这个目录在有些Linux系统下就是一个单独的分区,存放一些这台机子所属的那个用户的文件。里面的结构与/usr是一样的;

/usr/shared,/usr/share这里保存着各种共享文件。

5.2 管理文件与目录(实务12)

Linux系统中,文件与目录的操作是最基本、最重要的技术。用户可以方便、高效地通过系统提供的命令对文件和目录进行操作,本节将分别对这些基本命令进行介绍。

5.2.1 显示文件内容

用户要查看一个文件的内容时,可以根据显示要求的不同选用以下的命令。

1.cat命令

该命令的主要功能是用来显示文件,依次读取其后所指文件的内容并将其输出到标准输出设备上。另外,还能够用来链接两个或多个文件,形成新的文件。

该命令的使用形式为:cat [选项] 文件名。

cat命令中各个选项的含义为:

● - v:用一种特殊形式显示控制字符,LFD与TAB除外;

● - T:将TAB显示为“ù I”。该选项要与- v选项一起使用。即如果没有使用- v选项,则这个选项将被忽略;

● - E:在每行的末尾显示一个$符。该选项要与- v选项一起使用;

● - u:输出不经过缓冲区;

● - A:等同于- vET;

● - t:等同于- vT;

● - e:等同于- vE。

下面给出使用该命令的例子:

      //在屏幕上显示出Readme.txt文件的内容
      #cat Readme.txt
      //屏幕上显示出Readme.txt文件的内容,如果文件中含有特殊字符的话,一起显示出来
      #cat - A Readme.txt
      //把文件test1和文件test2的内容合并起来,放入文件test3中
      #cat test1 test2 > test3
      //此时在终端屏幕上不能直接看到该命令执行后的结果,也就是文件test3的内容,若想看到连
      //接后的文件内容,可以使用“cat test3”命令
      #cat test3              //显示文件test3的内容

2.more命令

在查看文件过程中,因为有的文本过于庞大,文本在屏幕上迅速地闪过,用户来不及看清其内容。该命令就可以一次显示一屏文本,显示满之后,停下来,并在终端底部打印出- - More- -,系统还将同时显示出已显示文本占全部文本的百分比,若要继续显示,按回车或空格键即可。

该命令的使用形式为:more [选项] 文件名。

more命令中部分常用选项的含义如下:

● - p:显示下一屏之前先清屏;

● - c:作用同- p类似;

● - d:在每屏的底部显示更友好的提示信息为:- - More- -(XX%)[Press space to contiune , ‘q’ to quit . ];

● - s:文件中连续的空白行压缩成一个空白行显示。

另外,在more命令的执行过程中,用户可以使用其一系列命令动态地根据需要来选择显示的部分。more在显示完一屏内容之后,将停下来等待用户输入某个命令。下面列出常用的几种:

● - i:n在命令行中指定了多个文件名的情况下,可用此命令使之显示第i个文件,若i过大(出界),则显示文件名列表中的最后一个文件;

● - i:p在命令行中指定了多个文件名的情况下,可用此命令使之显示倒数第i个文件,若i过大(出界),则显示第一个文件;

● - i:f显示当前文件的文件名和行数。

注意

上面三个命令中的n、p和f仅配合命令使用,没有具体的意义,只要依据其规定使用即可。

下面给出示例,说明如何使用上述命令及参数:

      //用分页的方式显示文件xattr.c的内容
      #more Makefile
      //下面为文件内容
      CC            = gcc -g
      # include path hash should be changed.
      INCLUDES       = -I../../include -I/usr/include/pcap -I./include
      #INCLUDES      = -I../../include -I/usr/include/pcap -I../../include
      CFLAGS         = -Wall -Wstrict-prototypes $(INCLUDES) \
                    `libnet-config --defines`
      SOURCES        = smtp_ns.c
      OBJS          = $(SOURCES:.c=.o)
      TARGETS        = smtp_ns
      # this is just for test
      .PHONY: all clean deps test
      all: $(TARGETS)
      clean:
            rm -f $(TARGETS) *.o core core.* *~
      smtp_ns:       smtp_ns.c
      --More--(88%)   //文件显示百分比为88%,说明还有部分内容一整屏难以显示
      //显示Rules.make文件的内容,但显示之前先清屏,并且在屏幕的最下方显示完整的百分比
      #more - dc example1.c
      //下面为文件内容
      # This file contains rules which are shared between multiple Makefiles.
      # False targets.
      .PHONY: dummy
      #
      # Special variables which should not be exported
      #
      unexport EXTRA_AFLAGS
      unexport EXTRA_CFLAGS
      unexport EXTRA_LDFLAGS
      unexport EXTRA_ARFLAGS
      unexport SUBDIRS
      unexport SUB_DIRS
      unexport ALL_SUB_DIRS
      unexport MOD_SUB_DIRS
      unexport O_TARGET
      unexport ALL_MOBJS
      --More--(4%)[Press space to continue, 'q' to quit.]
      //显示COPYING文件的内容,要求每10行显示一次,且显示之前先清屏
      #more - c -10 COPYING
      //显示文件的前10行内容
      NOTE! This copyright does *not* cover user programs that use kernel
      services by normal system calls - this is merely considered normal use
      of the kernel, and does *not* fall under the heading of "derived work"
      Also note that the GPL below is copyrighted by the Free Software
      Foundation, but the instance of code that it refers to (the Linux
      kernel) is copyrighted by me and others who actually wrote it
      Also note that the only valid version of the GPL as far as the kernel
      is concerned is _this_ license (ie v2), unless explicitly otherwise
      stated.--More--(2%)

3.less命令

该命令的功能和more命令的功能基本相同,也是用来按页显示文件,不同之处在于less命令在显示文件时允许用户既可以向前又可以向后地翻阅文件,而more命令只能向后翻阅文件。由于该命令参数的使用与more命令类似,在此不再赘述。

该命令的使用形式为:less文件名。

如果要按页显示test文件,则执行如下命令:

      #less test

如果要向后翻阅,可以使用键盘的“Page UP”键;要向前翻阅文件,则使用键盘的“Page Down”键即可。

4.head命令

该命令只显示文件或标准输入(从计算机的标准输入设备中得到的信息流,通常是指从键盘、鼠标等获得的数据)的头几行内容。如果用户希望查看一个文件究竟保存的是什么内容,只要查看文件的头几行,而不必浏览整个文件,便可以使用这个命令。

该命令的使用形式为:head [n值] 文件名。

该命令用来显示每个指定文件的前面n行。如果没有给出n值,默认设置为10。如果没有指定文件,head可从标准输入读取。例如:显示文件test.c的前3行。

      #head -3 test.c
      //前3行的具体内容
      #include <stdio.h>
      #include <sring.h>
      int main()

5.tail命令

该命令和head命令的功能相对应。如果想查看文件的尾部,可以使用tail命令。该命令显示一个文件的指定内容。它把指定文件的指定显示范围内的内容显示在标准输出上。同样,如果没有给定文件名,则使用标准输入文件。

该命令的使用形式为:tail [选项] 文件名。

tail命令中各个选项的含义为:

● - +num:从第num行以后开始显示;

● - -num:从距文件尾num行处开始显示。如果省略num参数,系统默认值为10;

● - l:以文本行为num的计数单位。与参数选项+num或-num选项同时使用时,num表示要显示的文本行行数;

● - c:以字节为num的计数单位。与参数选项+num或-num选项同时使用时,num表示要显示的字符数。

注意

l、c选项可以省略,系统默认值为l,即按行计。

例如:

      //显示文件example的最后4行
      #tail -4 example

5.2.2 文件内容查询

文件内容查询命令主要是指grep、fgrep和egrep命令。这组命令以指定的查找模式搜索文件,通知用户在什么文件中搜索到与指定的模式匹配的字符串,并且打印出所有包含该字符串的文本行,该文本行的最前面是该行所在的文件名。grep命令一次只能搜索一个指定的模式;egrep命令检索扩展的正则表达式(包括表达式组和可选项);fgrep命令检索固定字符串,并不识别正则表达式,是一种更为快速的搜索命令。

这组命令在搜索与定位文件中特定的主题和关键词方面非常有效。可以用其来搜索文件中包含的这些关键词。总的来说,grep命令的搜索功能比fgrep强大,因为grep命令的搜索模式可以是正则表达式,而fgrep却不能。

说明

正则表达式是一种用来描述文本模式的特殊语法。一个正则表达式由普通字符(例如字符a到z)及特殊字符(称为元字符,如/、*、?等)组成。简单地说,一个正则表达式就是需要匹配的字符串。

该组命令中的每一个命令都有一组选项,利用这些选项可以改变其输出方式。例如,可以在搜索到的文本行上加入行号,或者只输出文本行的行号,或输出所有与搜索模式不匹配的文本行,或只简单地输出已搜索到指定模式的文件名,并且可以指定在查找模式时忽略大小写。

这组命令在指定的输入文件中查找与模式匹配的行。如果没有指定文件,则从标准输入中读取。正常情况下,每个匹配的行都被显示到标准输出。如果要查找的文件是多个,则在每一行输出之前加上文件名。

该组命令的使用方式如下:

      grep [选项] [查找模式] [文件名1,文件名2,……]
      egrep [选项] [查找模式] [文件名1,文件名2,……]
      fgrep [选项] [查找模式] [文件名1,文件名2,……]

下面列出常用的部分命令选项:

● - b:在输出的每一行前显示包含匹配字符串的行在文件中的字节偏移量;

● - c:只显示匹配行的数量;

● - i:比较时不区分大小写;

● - h:在查找多个文件时,指示grep不要将文件名加入到输出之前;

● - l:显示首次匹配串所在的文件名并用换行符将其隔开。当在某文件中多次出现匹配串时,不重复显示此文件名;

● - n:在输出前加上匹配串所在行的行号(文件首行行号为1);

● - v:只显示不包含匹配串的行;

● - x::只显示整行严格匹配的行。

下面给出一些使用grep命令的例子,该组其他命令的使用方法和该命令是一样的:

      #grep ‘text file’stdc.h   //在文件stdc.h中搜索字符串“text file”
      #grep data *                //搜索出当前目录下所有文件中含有“data”字符串的行
      #grep stdio.h *.c           //在C程序文件中搜索包含有“stdio.h”头文件的所有文件

5.2.3 文件查找

用户进行文件查找时,可以使用如下介绍的几种命令。

1.find命令

该命令的功能是从指定的目录开始,递归地搜索其各个子目录,查找满足寻找条件的文件,并对之采取相关的操作。此命令提供了相当多的查找条件,功能非常强大。

该命令的使用形式为:find [选项] 文件名。

find命令提供的寻找条件可以是一个用逻辑运算符not、and、or组成的复合条件。逻辑运算符and、or、not的含义为:

● - and:逻辑与,在命令中用“-a”表示,是系统默认的选项,表示只有当所给的条件都满足时,寻找条件才满足;

● - or:逻辑或,在命令中用“-o”表示。该运算符表示只要所给的条件中有一个满足时,寻找条件就满足;

● - not:逻辑非,在命令中用“!”表示。该运算符表示查找不满足所给条件的文件。

该命令的查找方式主要是以名称和文件属性查找,参数如下:

● - name‘字符串’:查找文件名匹配所给字符串的所有文件,字符串内可用通配符*、?、[ ];

● - lname‘字符串’:查找文件名匹配所给字符串的所有符号链接文件,字符串内可用通配符*、?、[ ];

● -gid n:查找属于ID号为n的用户组的所有文件;

● -uid n:查找属于ID号为n的用户的所有文件;

● -group‘字符串’:查找属于用户组名为所给字符串的所有的文件;

● -user‘字符串’:查找属于用户名为所给字符串的所有的文件;

● -empty:查找大小为0的目录或文件;

● -path‘字符串’:查找路径名匹配所给字符串的所有文件,字符串内可用通配符*、?、[ ];

● -perm权限:查找具有指定权限的文件和目录,权限的表示可以如711(表示文件/目录所有者具有读写、执行权限,同组用户和系统其他用户只具有执行权限),644(文件/目录所有者具有读写权限,同组用户和系统其他用户之具有读权限)等,具体如何设置数字权限形式,读者请参看本章后面对文件/目录访问权限管理的介绍;

● -size n[bckw]:查找指定文件大小的文件,n后面的字符表示单位,默认为b,代表512字节的块。

该命令也提供了对查找出来的文件进行特定操作的选项:

● - exec命令名称{}:对符合条件的文件执行所给的Linux命令,而不询问用户是否要执行该命令。{}表示命令的参数即为所找到的文件;命令的末尾必须以“\;”结束;

● - ok命令名称{}:对符合条件的文件执行所给的Linux命令,与exec不同的是,它会询问用户是否要执行该命令;

● - ls:详细列出找到的所有文件;

● - fprintf文件名:将找到的文件名写入指定文件;

● - print:在标准输出设备上显示查找出的文件名。

说明

通配符*表示一个字符串;?只代表一个字符。它们只能通配文件名或扩展名,不能全都表示。

下面给出使用该命令的例子:

      //查找当前目录中所有以main开头的文件,并显示这些文件的内容
      #find . - name ‘main*’ - exec more {} \;
      //删除当前目录下所有一周之内没有被访问过的a .out或*.o文件
      #find . \(- name a.out - o - name ‘*.o’\)\
      > - atime +7- exec rm {} \;
      //寻找三个给定条件都满足的所有文件
      #find -name ’tmp’ -xtype c -user ’inin’
      //查询文件名为‘tmp’或是匹配‘mina*’的所有文件
      #find -name ’tmp’ -o -name ’mina*’
      //命令查询文件名不是‘tmp’的所有文件
      #find ! -name ’tmp’

2.locate命令

该命令也用于查找文件,比find命令的搜索速度快。使用时需要一个数据库,这个数据库由每天的例行工作(crontab)程序来建立。建立好数据库后,就可以方便地用来搜寻所需文件了。

该命令的使用形式为:locate [选项] 文件名。

说明

crontab命令用于安装、删除或者列出用于驱动cron后台进程的表格。用户把要执行的命令序列放到crontab文件中以获得执行,每个用户都可以有自己的crontab文件。

例如,在/usr/src/linux-2.4目录下查找包含有字符串“stdio.h”的所有文件:

      #locate /usr/src/linux-2.4
      //部分查询所得的文件
      /usr/lib/perl5/5.6.0/i386-linux/CORE/nostdio.h
      /usr/lib/bcc/include/stdio.h
      /usr/include/isc/stdio.h
      /usr/include/bits/stdio.h
      /usr/include/stdio.h
      /usr/src/linux-2.5.22/arch/ppc/boot/include/nonstdio.h
      /usr/src/linux-2.5.22/arch/ppc/xmon/nonstdio.h

5.2.4 文件处理

文件处理命令包括sort和uniq,下面分别对其进行介绍。

1.sort命令

该命令的功能是对文件中的各行进行排序。它有许多非常实用的选项,它们最初是用来对数据库格式的文件内容进行各种排序操作的。实际上,sort命令可以被认为是一个非常强大的数据管理工具,用来管理内容类似数据库记录的文件。

该命令将逐行地对文件中的内容进行排序,如果两行的首字符相同,该命令将继续比较这两行的下一字符。sort排序是根据从输入行抽取的一个或多个关键字进行比较来完成的。排序关键字定义了用来排序的最小的字符序列。在默认情况下,以整行为关键字按ASCII字符顺序进行排序。

该命令的使用形式为:sort [选项] 文件名。

该命令改变默认设置的选项主要有:

● - m:若给定文件已排好序,合并文件;

● - c:检查给定文件是否已排好序,如果它们没有都排好序,则打印一个出错信息,并以状态值1退出;

● - u:对排序后认为相同的行只保留其中一行;

● - o:输出文件将排序输出写到输出文件中而不是标准输出,如果输出文件是输入文件之一,sort便将该文件的内容写入一个临时文件,然后再排序和写输出结果。

该命令改变默认排序规则的选项主要有:

● - d:按字典顺序排序,比较时仅字母、数字、空格和制表符有意义;

● - f:将小写字母与大写字母同等对待;

● - I:忽略非打印字符;

● - M:作为月份比较:“JAN”<“FEB”<? <“DEC”;

● - r:按逆序输出排序结果;

● +posl-pos2:指定一个或几个字段作为排序关键字,字段位置从posl开始到pos2为止(包括posl,不包括pos2)。如不指定pos2,则关键字为从posl到行尾。字段和字符的位置从0开始;

● - b:在每行中寻找排序关键字时忽略前导的空白(空格和制表符);

● - t separator:指定字符separator作为字段分隔符。

下面给出几个使用该命令的例子:

      //用sort命令对text文件中各行排序后输出其结果
      #cat text       //查看text未排序前原文件内容
      //text原文件内容
      vegetable soup
      fresh vegetables
      fresh fruit
      lowfat milk
      #sort text      //对该文件进行排序
      //显示排序后结果
      fresh fruit
      fresh vegetables
      lowfat milk
      vegetable soup
      //用户可以保存排序后的文件内容,或把排序后的文件内容输出至打印机。下例中用户把排序后的
      //文件内容保存到名为result的文件中
      #sort text>result
      //以第2个字段作为排序关键字对文件example的内容进行排序
      #sort +1-2 example
      //对于file1和file2文件内容反向排序,结果放在outfile中,利用第2个字段的第一个字
      //符作为排序关键字
      #sort -r -o outfile +1.0-1.1 example
      //sort排序常用于在管道中与其他命令连用,组合完成比较复杂的功能,如利用管道将
      //当前工作目录中的文件送给sort进行排序,排序关键字是第6个至第8个字段
      #ls - l | sort +5-7

注意

字段编号从0开始计算。

sort命令也可以对标准输入进行操作。例如,如果想把几个文件文本行合并,并对合并后的文本行进行排序,可以首先用命令cat把多个文件合并,然后用管道操作把合并后的文本行输入给命令sort,sort命令将输出这些合并及排序后的文本行。在下面的例子中,文件veglist与文件fruitlist的文本行经过合并与排序后被保存到文件clist中。

      #cat veglist fruitlist | sort > clist

2.uniq命令

文件经过处理后在它的输出文件中可能会出现重复的行。例如,用cat命令将两个文件合并后,再使用sort命令进行排序,就可能出现重复行。这时可以用uniq命令将这些重复行从输出文件中删除,只留下每条记录的唯一样本。说明

这个命令读取输入文件,并比较相邻的行。在正常情况下,第二个及以后更多个重复行将被删去,行比较是根据所用字符集的排序序列进行的。该命令加工后的结果写到输出文件中。输入文件和输出文件不能相同。如果输入文件用“- ”表示,则从标准输入读取。

该命令的使用形式为:uniq [选项] 文件名。

该命令各选项含义如下:

● - d:只显示重复行;

● - u:只显示文件中不重复的行;

● - c:显示输出中,在每行行首加上本行在文件中出现的次数。它可取代- u和- d选项;

● - n:前n个字段与每个字段前的空白一起被忽略。一个字段是一个非空格、非制表符的字符串,彼此由制表符和空格隔开(字段从0开始编号);

● + n:前n个字符被忽略,之前的字符被跳过(字符从0开始编号);

● - f n:与-n相同,这里n是字段数;

● - s n:与+n相同,这里n是字符数。

下面是使用该命令的实例:

      #uniq -u example        //显示文件example中不重复的行
      //显示文件example中不重复的行,从第2个字段的第2个字符开始作比较。
      #uniq - u -1 +1 example

5.2.5 文件内容统计

文件内容统计命令主要是指wc命令。该命令统计给定文件中的字节数、字数、行数。如果没有给出文件名,则从标准输入读取。wc同时也给出所有指定文件的总统计数。字是由空格字符区分开的最大字符串。

该命令的使用形式为:wc [选项] 文件名。

该命令各选项含义如下,它们可以结合使用:

● - c:统计字节数;

● - l:统计行数;

● - w:统计字数。

下面给出使用该命令的例子:

      //统计文件README的行数、字节数和字数
      #wc -lcw README
          303   2265   14242 README
      //对文件README和README.freeswan进行行数、字节数、字数的统计
      #wc -lcw README README.freeswan
          303   2265   14242 README
          174    766   5585 README.freeswan
          477   3031   19827 total

说明

上面的选项顺序可以随意调换,而统计的结果形式相同。

5.2.6 文件比较

Linux系统中可以使用comm和diff命令比较文件的异同,下面分别对这两个命令进行介绍。

1.comm命令

该命令是对两个已经排好序的文件进行比较。其中file1和file2是已排序的文件(如果没有,可以使用上述的sort命令先进行排序)。comm读取这两个文件,然后生成三列输出:仅在file1中出现的行;仅在file2中出现的行;在两个文件中都存在的行。如果文件名用“-”,则表示从标准输入读取。

该命令的使用形式为:comm [选项] 文件名。

选项1、2或3控制相应的列显示与否。例如comm -12就只显示在两个文件中都存在的行;comm -23只显示在第一个文件中出现而未在第二个文件中出现的行;comm -123则什么也不显示。

下面给出使用该命令的例子:

      //对文件app.c和app1.c进行比较
      #cat app.c
      //待比较文件app.c内容
      #include <stdio.h>
      #include <string.h>
      #include <stdlib.h>
      void main()
      {
      int count = 0;
      printf("hello,world!\n");
      }
      //显示待比较文件app1.c内容
      #cat app1.c
      #include <stdio.h>
      #include <string.h>
      void main()
      {
      int count ;
      char *s = "hello,world";
      printf("hello,world!\n");
      }
      //对上述文件进行比较,显示两个文件中共有行的内容
      #comm -12 app.c app1.c
      #include <stdio.h>
      #include <string.h>
      void main()
      {
      printf("hello,world!\n");
      }
      //对上述文件进行比较,显示在第一个文件中出现,而不在第二个文件中出现的内容
      #comm -23 app.c app1.c
      #include <stdlib.h>
      int count = 0;

2.diff命令

该命令的功能为逐行比较两个文本文件,列出其不同之处。它对给出的文件进行系统地检查,并显示出两个文件中所有不同的行,不要求事先对文件进行排序。

该命令的使用形式为:diff [选项] 待比较文件1待比较文件2。

该命令运行后的输出通常由下述形式的行组成:

n1 a n3,n4;

n1,n2 d n3;

n1,n2 c n3,n4。

以上说明如何将file1转变成file2,从而给出了两个文本文件之间的差异。其中,字母(a、d、c)之前的行号(n1,n2)是针对file1的,其后面的行号(n3,n4)是针对file2的。字母a、d和c分别表示附加、删除和修改操作。

在上述形式的每一行的后面跟随受到影响的若干行,以“<”打头的行属于第一个文件,以“>”打头的行属于第二个文件。

说明

diff能区别块和字符设备文件以及FIFO(管道文件),不会把它们与普通文件进行比较。

如果file1和file2都是目录,则diff会产生很多信息。如果一个目录中只有一个文件,则产生一条信息,指出该目录路径名和其中的文件名。

diff各选项的含义如下:

● - b:忽略行尾的空格,而字符串中的一个或多个空格符都视为相等。如How are you与How are you被视为相同的字符串;

● - c:采用上下文输出格式(提供三行上下文);

● - C n:采用上下文输出格式(提供n行上下文);

● - e:产生一个合法的ed脚本作为输出;

● - r:当file1和file2是目录时,递归作用到各文件和目录上。

下面给出使用该命令的例子:

      //对文件app.c和app1.c进行比较
      #cat app.c
      //待比较文件app.c内容
      #include <stdio.h>
      #include <string.h>
      #include <stdlib.h>
      void main()
      {
      int count = 0;
      printf("hello,world!\n");
      }
      //显示待比较文件app1.c内容
      #cat app1.c
      #include <stdio.h>
      #include <string.h>
      void main()
      {
      int count ;
      char *s = "hello,world";
      printf("hello,world!\n");
      }
      //使用diff比较得出上述两个文件的不同之处
      #diff app.c app1.c
      3d2
      < #include <stdlib.h>
      6c5,6
      < int count = 0;
      ---
      > int count ;
      > char *s = "hello,world";

上述结果表示把文件app.c的第3行“#include <stdlib.h>”删除,并修改app.c文件的第5行“int count = 0;”和app1.c文件的第五行“int count ;”、第6行“char *s = "hello,world";”后,则两个文件相同。

5.2.7 文件的复制、移动和删除

文件的复制、删除和移动操作在Linux系统中使用得非常频繁,下面对这些操作的命令进行详细介绍。

1.cp命令

该命令的功能是将给出的文件或目录复制到另一文件或目录中,就如同DOS下的copy命令一样,功能非常强大。

该命令的使用形式为:cp [选项] 源文件或目录 目标文件或目录。

该命令的各选项含义如下:

● - a:该选项通常在复制目录时使用。它保留链接、文件属性,并递归地复制目录;

● - d:复制时保留链接;

● - f:删除已经存在的目标文件而不提示;

● - i:和f选项相反,在覆盖目标文件之前将给出提示要求用户确认。回答y时目标文件将被覆盖,是交互式复制;

● - p:此时cp除复制源文件的内容外,还将把其修改时间和访问权限也复制到新文件中;

● - r:若给出的源文件是一个目录文件,此时cp将递归复制该目录下所有的子目录和文件。此时目标文件必须为一个目录名;

● - l:不做复制,只是链接文件。

注意

为防止用户在不经意的情况下用cp命令破坏另一个文件,如用户指定的目标文件名是一个已存在的文件名,用cp命令复制文件后,这个文件就会被新复制的源文件覆盖。因此,建议用户在使用cp命令复制文件时,最好使用i选项。

下面举例说明该命令的使用:

      //将文件exam1.c复制到/usr/wang目录下,并改名为shiyan1.c
      #cp - i exam1.c /usr/wang/shiyan1.c
      //若不希望重新命名,可以使用下面的命令
      #cp exam1.c /usr/ wang/
      //将/usr/xu目录中的所有文件及其子目录复制到目录/usr/liu中
      #cp - r /usr/xu/ /usr/liu/

2.mv命令

用户可以使用mv命令来为文件或目录改名或将文件由一个目录移入另一个目录中。该命令如同DOS下的ren和move的组合。

该命令的使用形式为:mv [选项] 源文件或目录 目标文件或目录

说明

根据mv命令中第二个参数类型的不同(是目标文件还是目标目录),mv命令将文件重命名或将其移至一个新的目录中。当第二个参数类型是文件时,mv命令完成文件重命名;此时,源文件只能有一个(也可以是源目录名),它将所给的源文件或目录重命名为给定的目标文件名。当第二个参数是已存在的目录名称时,源文件或目录参数可以有多个,mv命令将各参数指定的源文件均移至目标目录中。在跨文件系统移动文件时,mv先复制,再将原有文件删除,而链至该文件的链接也将丢失。

命令中各选项的含义为:

● - I:交互方式操作。如果mv操作将导致对已存在的目标文件的覆盖,此时系统询问是否重写,要求用户回答y或n,这样可以避免误覆盖文件;

● - f:禁止交互操作。在mv操作要覆盖某已有的目标文件时不给任何指示,指定此选项后,i选项将不再起作用。

如果所给目标文件(不是目录)已存在,此时该文件的内容将被新文件覆盖。

注意

为防止用户在不经意的情况下用mv命令破坏另一个文件,建议用户在使用mv命令移动文件时,最好使用i选项。

下面举例说明该命令的使用:

      //将/usr/xu中的所有文件移到当前目录(用“.”表示)中
      #mv /usr/xu/ * .
      //将文件wch.txt重命名为wjz.doc
      #mv wch.txt wjz.doc

3.rm命令

在Linux中创建文件很容易,系统中随时会有文件变得过时且毫无用处。用户可以用rm命令将其删除。该命令的功能为删除一个目录中的一个或多个文件,它也可以将某个目录及其下的所有文件及子目录均删除。对于链接文件,只是删除了链接,原有文件均保持不变。

该命令的使用形式为:rm [选项] 文件。

该命令的各选项含义如下:

● - f:忽略不存在的文件,从不给出提示;

● - r:指示rm将参数中列出的全部目录和子目录均递归地删除,如果没有使用- r选项,则rm不会删除目录;

● - i:进行交互式删除。

注意

使用rm命令要格外小心。因为一旦一个文件被删除,它是不能被恢复的。为了防止此种情况的发生,可以使用rm命令中的i选项来确认要删除的每个文件。如果用户输入y,文件将被删除。如果输入任何其他东西,文件将被保留。

在下一个例子中,用户想要删除文件test和example。系统会要求对每个文件进行确认。用户最终决定删除example文件,保留test文件。

      #rm -i test example
      Remove test ?n
      Remove example ?y

5.2.8 文件链接

文件链接命令是指ln命令。该命令在文件之间创建链接。这种操作实际上是给系统中已有的某个文件指定另外一个可用于访问它的名称。对于这个新的文件名,我们可以为其指定不同的访问权限,以控制对信息的共享和安全性的问题。

如果链接指向目录,用户就可以利用该链接直接进入被链接的目录而不必使用较长的路径名。而且,即使我们删除这个链接,也不会破坏原来的目录。

链接有两种,一种被称为硬链接(Hard Link);另一种被称为符号链接(Symbolic Link),也称为软链接。建立硬链接时,链接文件和被链接文件必须位于同一个文件系统中,并且不能建立指向目录的硬链接。而对于符号链接,则不存在这个问题。默认情况下,ln产生硬链接。

在硬链接的情况下,参数中的“目标”被链接至[链接名]。如果[链接名]是一个目录名,系统将在该目录之下建立一个或多个与“目标”名的链接文件,链接文件和被链接文件的内容完全相同。如果[链接名]为一个文件,用户将被告知该文件已存在且不进行链接。如果指定了多个“目标”参数,那么最后一个参数必须为目录。

如果给ln命令加上- s选项,则建立符号链接。如果[链接名]已经存在但不是目录,将不做链接。[链接名]可以是任何一个文件名(可包含路径),也可以是一个目录,并且允许其与“目标“不在同一个文件系统中。如果[链接名]是一个已经存在的目录,系统将在该目录下建立一个或多个与“目标“同名的文件,此新建的文件实际上是指向原“目标”的符号链接文件。

注意

在使用文件链接的时候,方法与普通文件的使用方法完全相同,所以这里不再重复介绍。

该命令的使用形式为:ln [选项] 目标 [链接名]。

下面举例说明该命令的使用:

      //用户为当前目录下的文件lunch创建了一个符号链接/home/xu
      #ln - s lunch /home/xu
      //使用建立的软链接查看文件,实际查看的是原文件lunch的内容
      #cat /home/xu

5.2.9 目录的创建与删除

下面介绍Linux系统中目录的创建以及删除命令的使用。

1.mkdir命令

该命令的使用形式为:mkdir [选项] dirname。

该命令创建由dirname命名的目录。要求创建目录的用户在当前目录中(dirname的父目录中)具有写权限,并且dirname不能是当前目录中已有的目录或文件名称。

命令中各选项的含义为:

● - m:对新建目录设置存取权限,也可以用chmod命令设置;

● - p:可以是一个路径名称。此时若路径中的某些目录不存在,加上此选项后,系统将自动建立好这些不存在的目录,即一次可以建立多个目录。

例如:在当前目录中建立inin和inin下的/mail目录,也就是连续建两个目录。

        #mkdir - p - m 700 ./inin/mail/

该命令的执行结果是在当前目录中创建嵌套的目录层次inin /mail,权限设置为只有文件所有者有读、写和执行权限。

2.rmdir命令

该命令的使用形式为:rmdir [选项] dirname。

dirname表示目录名。该命令从一个目录中删除一个或多个子目录项。

需要注意的是,一个目录被删除之前必须是空的。删除某目录时也必须具有对父目录的写权限。

注意

rm - r dir命令可代替rmdir,但是有很大的危险性。

命令中选项的含义为:

● - p:递归删除目录dirname,当子目录删除后其父目录为空时,也一同被删除。如果整个路径被删除或者由于某种原因保留部分路径,则系统在标准输出上显示相应的信息。

例如要将/usr/xu/txt目录删除,命令如下:

        #rmdir - p /usr/xu/txt

5.2.10 改变工作目录、显示路径以及显示目录内容

Linux系统分别使用cd、pwd以及ls命令来改变工作目录、显示路径以及显示目录的内容,下面对这些命令进行介绍。

1.cd命令

该命令的使用形式为:cd [directory]。

该命令将当前目录改变为directory所指定的目录。若没有指定directory,则回到用户的主目录。为了改变到指定目录,用户必须拥有对指定目录的执行和读权限。该命令可以使用通配符。

假设用户当前目录是:/home/working,若要更换到/usr/src目录中,则使用如下命令:

        #cd /usr/src

2.pwd命令

该命令的使用形式为:pwd。

在Linux层次目录结构中,用户可以在被授权的任意目录下用mkdir命令创建新目录,也可以用cd命令从一个目录转换到另一个目录。然而,没有提示符来告知用户目前处于哪一个目录中。要想知道当前所处的目录,可以用pwd命令,该命令显示整个路径名。注意

此命令显示当前工作目录的绝对路径,而不是相对路径。

例如使用该命令显示当前工作路径,命令如下:

        #pwd
        /home/working

3.ls命令

该命令的使用形式为:ls [选项] [目录或是文件]。

ls是英文单词list的简写,其功能为列出目录的内容。这是用户最常用的命令之一,因为用户要不时地查看某个目录的内容。该命令类似于DOS下的dir命令。对于每个目录,该命令将列出其中所有的子目录与文件。对于每个文件,ls将输出其文件名以及所要求的其他信息。默认情况下,输出条目按字母顺序排序。当未给出目录名或文件名时,就显示当前目录的信息。

命令中部分常用选项的含义如下。

● - a:显示指定目录下所有的子目录与文件,包括隐藏文件。

● - A:显示指定目录下所有的子目录与文件,包括隐藏文件。但不列出“.”和“..”。

● - d:如果参数是目录,只显示其名称而不显示其下的各个文件,且往往与l选项一起使用,以得到目录的详细信息。

● - l:以长格式来显示文件的详细信息。这个选项最常用,每行列出的信息依次是:

文件类型与权限 链接数 文件属主 文件属组 文件大小 建立或最近修改的时间名字

对于符号链接文件,显示的文件名之后有“—〉”和引用文件路径名。

对于设备文件,其“文件大小”字段显示主、次设备号,而不是文件大小。目录中的总块数显示在长格式列表的开头,其中包含间接块。

● - L:若指定的名称为一个符号链接文件,则显示链接所指向的文件。

● - m:输出按字符流格式,文件跨页显示,以逗号分开。

● - n:输出格式与l选项相同,只不过在输出中文件属主和属组是用相应的UID号和GID号来而不是实际的名称表示的。

● - R:递归式地显示指定目录的各个子目录中的文件。

用ls - l命令显示的信息中,开头是由10个字符构成的字符串,其中第一个字符表示文件类型,它可以是下述类型之一:

● -:普通文件;

● d:目录;

● l:符号链接;

● b:块设备文件;

● c:字符设备文件。

后面的9个字符表示文件的访问权限,分为3组,每组3位。第一组表示文件属主的权限,第二组表示同组用户的权限,第三组表示其他用户的权限。每一组的三个字符分别表示对文件的读、写和执行权限。

各权限如下所示:

● r:读;

● w:写;

● x:执行,对于目录,表示进入权限;

● s:当文件被执行时,把该文件的UID或GID赋予执行进程的UID(用户ID)或GID(组ID);

● t:设置标志位(留在内存,不被换出)。如果该文件是目录,在该目录中的文件只能被超级用户、目录拥有者或文件属主删除。如果是可执行文件,在该文件执行后,指向其正文段的指针仍留在内存。这样再次执行它时,系统就能更快地装入该文件;

● -:没有设置权限。

下面给出使用该命令的例子:

        //列出当前目录的内容
        #ls -A
        freeswan-2.05  linux-2.4.18   linux-2.5.22  redhat
        linux-2.4     linux-2.4.7-10  modules
        //列出某个目录的内容
        #ls -A /home/liyang
        .bash_history  .bashrc  .kde     test.c
        app1.c    .bash_logout   .emacs   libpcap1        .screenrc
        app.c     .bash_profile  .gtkrc   libpcap.tar.gz  test1.c
        //用长格式列出某个目录下所有的文件(包括隐藏文件)
        #1s -la /home/liyang
        total 1248
        -rw-r--r--   1 root     root         118  May 24 13:35 app1.c
        -rw-r--r--   1 root     root         116  May 24 13:34 app.c
        -rw-------   1 liyang   liyang       156 Nov 23 17:14 .bash_history
        -rw-r--r--   1 liyang   liyang        24 Nov 23 17:03 .bash_logout
        -rw-r--r--   1 liyang   liyang       191 Nov 23 17:03 .bash_profile
        -rw-r--r--   1 liyang   liyang       124 Nov 23 17:03 .bashrc
        -rw-r--r--   1 liyang   liyang       820 Nov 23 17:03 .emacs
        -rw-r--r--   1 liyang   liyang       118 Nov 23 17:03 .gtkrc
        drwxr-xr-x   3 liyang   liyang       4096 Nov 23 17:03 .kde
        drwxr-xr-x   7 chenhq   xiang        4096 Jun 25 18:51 libpcap1
        -rw-r--r--   1 root     root      925063 Aug  5   2003 libpcap.tar.gz
        -rw-r--r--   1 liyang   liyang       3511 Aug 23 17:03 .screenrc
        -rw-r--r--   1 root     root         153  Aug 11 17:58 test1.c
        -rw-r--r--   1 root     root         414  Mar 28 12:02 test.c
        //用长格式列出某个目录下所有的文件包括隐藏文件和它们的i节点号。并把文件属主和属组以
        //UID号和GID号的形式显示
        #1s -1ain /home/patterson
        total 220
        654695 drwxrwxr-x   4508     508         4096    May 19 10:28 .
        639756 drwx------   7541     541         4096    May 24 13:38 ..
        654759-rwxr-xr-x   1 0       0           137332  Jun 18 15:45 tux
        654698-rw-rw-r--   1508     508         8876    Aug 14  2003 tap.c
        654696-rw-r--r--   1 0       0          33264    Jun 18 15:45 tap.o
        654699 drwx------   5508     508         4096    Aug 13  2003 libnids-1.17
        686839 drwxr-xr-x   2 0       0          16384    Aug 19 10:34 log
        654697-rw-rw-r--   1508     508           260   Nov 13  2003 Makefile

5.3 文件/目录访问权限管理(实务13)

Linux系统中的每个文件和目录都有访问许可权限,通过其确定谁可以通过何种方式对文件和目录进行访问和操作。本节将对文件/目录访问的方法和命令进行介绍。

5.3.1 了解文件/目录访问权限

文件或目录的访问权限分为只读,只写和可执行三种。以文件为例,只读权限表示只允许读其内容,而禁止对其做任何的更改操作;只写权限允许对文件进行任何的修改操作;可执行权限表示允许将该文件作为一个程序执行。文件被创建时,文件所有者自动拥有对该文件的读、写和可执行权限,以便于对文件的阅读和修改。用户也可根据需要把访问权限设置为需要的任何组合。

有三种不同类型的用户可对文件或目录进行访问:文件所有者,同组用户和其他用户。文件所有者一般是文件的创建者,它可以允许同组用户有权访问文件,还可以将文件的访问权限赋予系统中的其他用户。在这种情况下,系统中的每一位用户都能访问该用户拥有的文件或目录。

每一个文件或目录的访问权限都有三组,每组用三位表示,分别为文件属主的读、写和执行权限;与属主同组的用户的读、写和执行权限;系统中其他用户的读、写和执行权限。当用ls -l命令显示文件或目录的详细信息时,最左边的一列为文件的访问权限。例如:

        #ls -l sobsrc.tgz
        -rw-r--r--1 root root 483997 Ju1 l5 17:3l sobsrc.tgz

横线代表空许可(即表示不具有该权限)。r代表只读,w代表写,x代表可执行。注意:这里共有10个位置。第1个字符指定了文件类型。在通常意义上,一个目录也是一个文件。如果第1个字符是横线,表示是一个非目录的文件。如果是d,表示是一个目录。后面的9个字符每三个构成一组,依次表示文件主、组用户、其他用户对该文件的访问权限。

例如:

        -rw-r--r--   sobsrc.tgz

表示文件sobsrc.tgz的访问权限,说明sobsrc.tgz是一个普通文件;sobsrc.tgz的属主有读写权限;与sobsrc.tgz属主同组的用户只有读权限;其他用户也只有读权限。

确定了一个文件的访问权限后,用户可以利用Linux系统提供的chmod命令来重新设定不同的访问权限。也可以利用chown命令来更改某个文件或目录的所有者。

5.3.2 使用chmod命令改变文件/目录的访问权限

chmod命令用于改变文件或目录的访问权限,它是一条非常重要的系统命令,用户可用其控制文件或目录的访问权限。

该命令有两种用法。一种是包含字母和操作符表达式的文字设定法,另一种是包含数字的数字设定法。

1.文字设定法

文字设定法的一般使用形式为:chmod [who] [+ | - | =] [mode] 文件名。

其中,操作对象who可以是下述字母中的任一个或者为各字母的组合:

● u表示“用户(user)”,即文件或目录的所有者;

● g表示“同组(group)用户”,即与文件属主有相同组ID的所有用户;

● o表示“其他(others)用户”;

● a表示“所有(all)用户”,其为系统默认值。

操作符号可以是:

● +添加某个权限;

● -取消某个权限;

● =赋予给定权限并取消其他所有权限(如果有的话)。

设置mode所表示的权限可用下述字母的任意组合:

● r:可读;

● w:可写;

● x:可执行。只有目标文件对某些用户是可执行的或该目标文件是目录时才追加x属性;

● s:在文件执行时把进程的属主或组ID设置为该文件的文件属主。方式“u+s”设置文件的用户ID位,“g+s”设置组ID位;

● t:将程序的文本保存到交换设备上;

● u:与文件属主拥有一样的权限;

● g:与和文件属主同组的用户拥有一样的权限;

● o:与其他用户拥有一样的权限。

说明

在一个命令行中可给出多个权限方式,其间用逗号隔开。

下面给出使用该设定法的例子:

        //设定文件sort的属性为:文件属主(u)增加执行权限;与文件属主同组用户(g)增加执行权
限;
        //其他用户(o)增加执行权限
        #chmod a+x sort
        //设定文件text的属性为:文件属主(u)增加写权限;与文件属主同组用户(g)增加写权限;
        //其他用户(o)删除执行权限
        #chmod ug+w,o-x text
        //对可执行文件sniffer添加s权限,使得执行该文件的用户暂时具有该文件拥有者的权限
        #chmod u+s sniffer

说明

当其他用户执行sniffer程序时,他的身份将由于这个程序而暂时变成该sniffer程序的拥有者(由于chmod命令中使用了s选项),所以他就能够读取sniffer.c文件(虽然这个文件被设定为其他人不具备任何权限),这就是s的功能。在整个系统中特别是root本身,最好不要过多地设置这种类型的文件(除非必要),这样可以保障系统的安全,避免因为某些程序的bug而使系统遭到入侵。

        //以下命令都是将文件readme.txt的执行权限删除
        #chmod a-x readme.txt
        #chmod -x readme.txt

2.数字设定法

数字设定法是与文字设定法功能等价的设定方法,只不过比文字设定法更加简便。数字表示的属性的含义为:0表示没有权限,1表示可执行权限,2表示可写权限,4表示可读权限,然后将其相加。所以数字属性的格式应为三个从0到7的八进制数,其顺序是(u)、(g)、(o)。其他的与文字设定法基本一致。

如果想让某个文件的属主有“读/写”两种权限,需要把4(可读)+2(可写)=6(读/写)。

数字设定法的一般形式为:chmod [mode] 文件名。

下面给出使用该数字设定法的例子:

        //设定文件mm.txt的属性为:文件属主(u)拥有读、写权限;与文件属主同组人用户(g)拥有
        //读权限;其他人(o)拥有读权限
        #chmod 644 mm.txt
        //设定fib.c这个文件的属性为:文件主本人(u)具有可读/可写/可执行权限;与文件主同组人
        //(g)可读/可执行权;其他人(o)没有任何权限
        #chmod 750 fib.c
        #ls -l      //使用ls查看执行结果
        -rwxr-x---1 inin users 44137 Oct 12 9:18 fib.c

5.3.3 使用chown命令更改文件/目录的所有权

该命令用来更改某个文件或目录的属主和属组。举个例子,root用户把自己的一个文件复制给用户xu,为了让用户xu能够存取这个文件,root用户应该把这个文件的属主设为xu,否则用户xu无法存取这个文件。

该命令的使用形式为:chown [选项]用户或组文件。

说明

chown将指定文件的拥有者改为指定的用户或组。用户可以是用户名或用户ID,组可以是组名或组ID。文件是以空格分开的、要改变权限的文件列表,支持通配符。

该命令的选项为:

● -R:递归地改变指定目录及其下面的所有子目录和文件的拥有者;

● -v:显示chown命令所做的工作。

下面给出使用该命令的例子:

        //把文件shiyan.c的所有者改为wang
        #chown wang shiyan.c
        //把目录/his及其下面的所有文件和子目录的属主改成wang,属组改成users
        #chown -R wang.users /his

5.3.4 使用setuid/setgid改变执行权限

通过前面的介绍我们知道,Linux系统中的每一个文件都有一个所有者,表示该文件是谁创建的。同时,该文件还有一个组编号,表示该文件所属的组,一般为文件所有者所属的组。并且,在一般情况下,我们也可以通过设定对文件的权限来控制对其的相关操作。

在此情况下,如果是一个可执行文件,那么在执行时,一般该文件只拥有调用该文件的用户具有的权限。而setuid/setgid则可以来改变这种设置:

● setuid:设置使文件在执行阶段具有文件所有者的权限。典型的文件是/usr/bin/passwd。如果一般用户执行该文件,则在执行过程中,该文件可以获得root权限,从而可以更改用户的密码;

● setgid:该权限只对目录有效。目录被设置该位后,任何用户在此目录下创建的文件都具有和该目录所属的组相同的组;

● sticky bit:该位可以理解为防删除位。一个文件是否可以被某用户删除,主要取决于该文件所属的组是否对该用户具有写权限。如果没有写权限,则这个目录下的所有文件都不能被删除,同时也不能添加新的文件。如果希望用户能够添加文件但同时不能删除文件。则可以对文件使用sticky bit位。设置该位后,j即便用户对目录具有写权限,也不能删除该文件。

在前面我们讨论了通过文字设定和数字设定的方法来设定文件/目录的访问权限问题,同样的道理,下面我们通过这两种方法来介绍如何操作这些标志。操作这些标志与操作文件权限的命令是一样的,都是使用chmod命令来进行的。

1.文字设定法

chmod u+s filename:为文件filename加上setuid标志。

chmod g+s dirname:为目录dirname目录加上setgid标志。

chmod o+t filename:为文件filename加上sticky标志。

2.数字设定法

对一般文件通过三组八进制数字来置标志,如444、777、644等。如果设置这些特殊标志,则在这组数字之前外加一组八进制数字。如4666、4777 等。这一组八进制数字三位的意义如下:

setuid位:如果该位为1,显示为“S”,则表示设置setuid,其显示在原来的x标志位上;

setgid位:如果该位为1,显示为“S”,则表示设置setgid,其显示在原来的x标志位上;

sticky位:如果该位为1,显示为“T”,则表示设置sticky,其显示在原来的x标志位上。

设置完这些标志后,可以用ls -l命令来查看。如果有这些标志,则会在原来的执行标志位置上显示。如下所示:

r-srw-r--:表示有setuid标志;

rwxrwsrw-:表示有setgid标志;

rwxrw-rwt:表示有sticky标志。说明

如果本来在该位上有x,则这些特殊标志显示为小写字母(s,s,t);否则,显示为大写字母(S,S,T)。

另外,读者还必需注意,虽然setuid/setgid机制非常方便实用,但是由于提升了执行者的权限,因而不可避免地存在许多安全隐患和风险,所以笔者不赞成广大读者广泛使用,并且,在实际的系统管理过程中,我们还经常需要找出设置有这些标志的文件,并对他们进行检查和清理,那么,一般我们可以使用如下命令来对系统中的具有特殊标志的文件进行寻找:

        #find -perm +6000-type f -exec ls -ld {}\; > setuid.txt&