• Linux操作系统(三):文件、目录


    • 关于本文内容的导读
    • Linux的文件权限
    • Linux的文件与目录管理

     一、关于本文内容的导读

    这部分不涉及具体内容的解析,只是作为浏览和查找相关知识点的引导内容,采用【主题 | 命令 | 对应内容小节编号】三个关键信息的组合模式,依照这些信息可以快速查找到相关详细的示例和解析。

    查看文件属性 | ls | 2.2
    修改用户组 | chgrp | 2.3
    修改用户拥有者 | chown | 2.3
    修改文件权限 | chmod | 2.3
    切换目录 | cd | 3.1
    打印当前所在目录 | pwd | 3.1
    创建目录 | mkdir | 3.1
    删除目录 | rmdir | 3.1
    当前工作目录下的$PATH变量 | 3.1
    复制文件或目录 | cp | 3.2
    删除文件或目录 | rm | 3.2
    移动文件或目录 | mv | 3.2
    查看文件路径的目录名 | dirname | 3.2
    查看文件路径的文件名 | basename | 3.2
    从第一行开始查看文件全部内容 | cat | 3.3
    从最后一行开始查看文件全部内容 | tac | 3.3
    从第一行开始查看文件内容并同时显示行号 | nl | 3.3
    翻页查看和检索文件内容 | more || less | 3.3
    只查看文件前几行内容 | head | 3.3
    只查看文件后几行内容 | tail | 3.3
    以二进制的方式查看文件内容 | od | 3.3
    查看文件信息并指定查看文件某个时间数据 | ll | 3.4
    修改文件时间 | touch | 3.4
    查看和设置当前目录下的默认权限 | umask | 3.5
    配置文件隐藏属性 | chattr | 3.5
    查看文件隐藏属性 | lsattr | 3.5
    查找命令的文件路径 | which | 3.7
    查找特定目录中的文件路径 | whereis | 3.7
    根据/var/lib/mlocate内的数据库记录,查找用户输入关键词的文件路径 | locate | 3.7
    更新/var/lib/mlocate内的数据库文件 | updatedb | 3.7
    查找文件的路径 | find | 3.7

     二、Linux的文件权限

    2.1简单的了解用户、用户组、非本用户组的其他人与文件权限

    Linux系统是一个多用户多任务的分时操作系统(CTSS),任何一个要使用系统资源的用户,都必须向系统管理员申请一个账号,然后以这个账号的身份进入系统。

    用户的账号一方面可以帮助系统管理员对使用系统的用户进行跟踪,并监控他们对系统资源的访问;另一方面也可以帮助用户组织文件,并为用户提供安全性保护。

    从文件权限的角度来说,用户、用户组、非本用户组就是将使用系统资源的用户分为三类,然后分别指定这三类用户对文件的操作权限,即对文件的读取、写入、执行权限。

    除了文件对应的用户分类以外,在系统上所有文件都对应着一个特殊的用户root,该用户对系统上所有文件具有全部操作权限。

    2.2Linux文件属性与ls命令

    使用 ls -al 查看文件属性:ls使用来查看文件信息的命令,选项al中的a表示显示所有文件信息(包括隐藏的文件,以'.'开头的文件),选项al中的l表示目录下的文件列表,如果不指定路径则查看当前目录下的文件信息,也可以查看指定路径下的文件信息:

     ls [ -options ] [ path ]

    更多关于ls命令的选项可以参考帮助文档,这里就不赘述了。在查看文件信息之前如果不是root登入系统,使用su切换到root超级管理员,不然可能当前用户没有查看文件的权限。以root身份执行 ls -al ,这里我选取部分文件信息作为示例:

    dr-xr-xr-x. 22 root root  4096 May 11 14:52 ..
    -rw-r--r--.  1 root root    18 May 20  2009 .bash_logout
    drwxr-xr-x.  3 root root  4096 May 10 10:28 .cache
    [    1   ] [2][ 3 ][ 4 ] [ 5 ][     6     ][    7     ] 

    打印出来的文件信息分了七个字段,这七个字段的含义分别是:

    1.文件类型与权限信息:该文件是文件还是文件夹,用户、用户组、其他用户分别拥有哪些权限;
    2.连接数:表示有多少个文件连接到此节点(inode/目录/文件夹),每个文件都会将它的权限与属性记录到文件系统的inode中,也就是记录到它所属的文件夹/文件节点上,这个连接数可以表示当前inode下又少个文件;
    3.文件拥有者:表示文件/目录拥有者的账号名称;
    4.文件所属用户组:表示这个文件所属的用户组;
    5.文件大小:表示文件的字节(Bytes)大小。
    6.文件最后被修改的时间:这栏内容分别为月/日及时间,如果时间距离当前比较久前面可能会显示年份。
    7.文件名:文件名没啥好说的,就是文件名前面多一个【.】开头的是隐藏文件,如果本来就是以【.】开头的话就会是两个点【..】

    文件类型与文件权限

    这里重点来解析一下 ls -al 打印的文件信息中第一个字段内容,即“文件类型与文件权限”。这个字段有十个字符,第一个字符用来表示文件的目录、文件、连接文件;后面九个字符三个一组分别表示:用户权限、用户组权限、其他用户权限。

    //第一个字符常见有下面五种类型:
    d;表示目录;
    -:表示文件;
    l:表示链接文件;
    b:表示设备文件里面的可供存储的周边设备(可按块随机读写的设备)
    c:表示设备文件里面的串行端口设备,例如键盘、鼠标(一次性读取设备)
    
    //三组权限字符的格式都是一样的,每连续三个为一组,三个字符的含义分别是:
    r/-:【r】代表可读read,每组的第一个字符要么是【r】,要么是【-】表示不可读;
    w/-:【w】代表可写write,每组的第二个字符要么是【w】,要么是【-】表示不可写;
    x/-:【x】代表可执行execute,每组的第三个字符要么是【x】,要么是【-】表示不可执行。

    ls命令的选项功能介绍:

    #ls的选项与参数:
    -a:全部的文件、连同隐藏文件(开头以“.”开头的文件)一起列出来
    -A:全部的文件、连同隐藏文件一起列出来,但不包括“.”和“..”这两个目录
    -d:仅列出目录本身,而不是列出目录内的文件数据
    -f:直接列出结果,而不进行排序(ls会默认以文件名排序)
    -F:根据文件、目录信息,附加数据解构,例如:*代表可执行文件、/代表目录、=代表socket文件、|代表FIFO文件
    -h:将文件容量以易读的方式列出来,如GB、KB等单位
    -i:列出inode号码
    -l:详细信息显示,包含文件的属性与权限等数据
    -n:列出UID与GID而非使用者的用户ID和用户组名称
    -r:将排序结果反向输出
    -R:连同子目录内容一起列出来,等于该目录下所有文件都会显示出来
    -S:以容量大小排序,而不是以文件名排序
    -t:以时间排序,而不是以文件名排序
    --color=never:不要依据文件特性给予颜色显示
    --color=always:显示颜色
    --color=auto:让系统自行依据设置来判断是否给予颜色
    --full-time:以完整时间模式输出,例如包含年、月、日、时、分
    --time={atime,ctime}:输出access时间或改变权限属性时间ctime,而非内容修改时间(modification time)

    2.3如何修改文件属性与权限

    修改文件所属用户组的命令chgrp

     chgrp [-R] dirname/filename groupname  #-R(可选)表示递归修改,子目录下的所有文件、目录都会被更新成这个用户组,filename可以是目录可以是文件

    比如当前目录下有一个文件的test.txt的所属用户组是tx,我要将其用户组修改为users:

     ls test.txt -al        #-rw-rw-r--. 1 tx tx 5 May 11 22:35 test.txt

     chgrp  test.txt users   #-R(可选)表示递归修改,子目录下的所有文件、目录都会被更新成这个用户组,filename可以是目录可以是文件

     ls test.txt -al       #-rw-rw-r--. 1 tx users 5 May 11 22:35 test.txt

    注意这里使用的用户组名称必须是在系统中存在的用户组,即在/etc/group文件中有记录存在的用户组。

    修改文件拥有者的命令chown

     chown [-R] 账号名称 文件/目录

     chown [-R] 账号名称:用户组 文件/目录  #可以同时修改文件的所有者和用户组

    比如将当前目录下的test.txt文件的拥有者修改为root,然后再将用户和用户组都修改为tx:

     ls test.txt -al      #-rw-rw-r--. 1 tx users 5 May 11 22:35 test.txt

     chown root test.txt #修改拥有者

     ls test.txt -al     #-rw-rw-r--. 1 root users 5 May 11 22:35 test.txt

     chown tx:tx test.txt   #修改拥有者和所属用户组

     ls test.txt -al     #-rw-rw-r--. 1 tx tx 5 May 11 22:35 test.txt

    为什么有了chgrp还要再chown中扩展修改用户组的功能呢?比如当你复制一个文件时,会同时将用户的权限一起复制过去,如果此时复制的文件拥有者和用户组都是root,那在这时候可能就需要同时修改文件的拥有者和所属用户组。

    修改文件的权限chmod命令

    Linux文件权限除了是可以使用符号和字母表示以外还可以使用数字表示:可读(r)的数值表示4、可写(w)的数值表示2、可执行(x)的数值表示1、禁止当前权限的数值表示0。

    采用数值表示权限是采用这三种权限的和来标识一个用户身份的权限,拿文件所有者来举例,当所有者的所有权限都开启时字母表示为rwx,对应数值421使用和表示权限就是7,也就是说当前文件拥有者的权限可以表示为7。以此类推,假设文件所有者的权限字母表示r-x,当前文件所有者的权限就是4+0+1=5;

    Linux文件用户的三种身份用字母表示:拥有者的字母简写表示u、用户组的字母简写表示g、其他用户的字母简介表示o、所有用户的字母简写表示a(单词all全部的意思)。

    在使用数值表示文件权限时,采用三位数来标识三种文件身份的权限:个位表示其他用户、十位表示用户组、百位表示拥有者。结合数值权限表示方式就可以采用一个三位数来标识文件的完整权限了,比如下面这些示例:

    -rw-r--r--:该文件对应的数值权限表示为644
    -rwx--x---:该文件对应的数值权限表示为710
    -r-x-wxr--:该文件对应的数值权限表示为534

     chmod [-R] xyz 文件或目录  #chmod命令的语法,-R(可选)表示递归修目录下所有文件的权限,连同子目录下的所有文件都会被修改

     chmod 644 test.txt       #修改当前目录下文件test.txt的权限为644,即用户可读可写、群组可读、其他用户可读

    除了使用三位数值的方式修改文件所有用户身份的权限,还可以通过符号类型来修改文件的权限,符号修改权限的方式有添加权限(+)、移除权限(-)、设置权限(=),并且可以使用逗号(,)间隔来实现一次指定多个单一身份修改权限。需要注意的是使用符号的方式修改权限时只能用权限的字符表示方式,不能使用数值来表达权限值,比如下面这些示例:

    chmod u=rwx,go=rx test.txt    //修改当前目录下文件test.txt的拥有者权限为rwx,用户组和其他用户的权限为rx
    chmod g+w test.txt            //修改当前目录下文件test.txt的用户组的可读权限为可读
    chmod a-x test.txt            //修改当前目录下文件test.txt的所有用户的可执行权限为不可执行

    2.4目录与文件的权限意义

    权限对文件的重要性

    文件实际上是含有数据的地方,包括一般文件、数据库文件、二进制可执行文件等,因此权限对文件的意义就是:可读(read,简写r)、可写(write,简写w)、可执行(eXecute,简写x)。

    可读简单的来说就是指将文件中获取数据。

    可写是指可以对文件进行写入、编辑、新增、修改文件内容的权限,但需要注意的是不具备删除文件本身的权限,对于文件的rwx权限而言只是相对文件内容而不是文件本身。

    可执行就是指可以将文件内容作为执行程序,但需要注意的是在Windows中可执行是采用文件后缀的方式来实现,Linux中采用x这个权限标识来实现,与文件名没有直接联系。

    权限对目录的重要性

    目录的主要内容是记录文件名列表,文件名与目录有强烈的关联,那么目录的r、w、x权限意义是什么呢?

    可读:对于目录的可读权限就是可以查看目录的文件列表,所以当由拥有目录的可读权限时就可以通过ls这个命令查看目录的文件列表内容。

    可写:对于目录的可写权限非常多,并且具备改动目录结构列表的权限,详细的目录可写权限参考下面的内容:

    1.新建文件或目录;
    2.删除已存在的文件或目录(不论该文件是什么权限);
    3.更改已存在的文件或目录的名称;
    4.移动该目录的文件、目录的位置;

    可执行:对于目录的可执行权限就是用户能否进入该目录称为用户的工作目录,所谓工作目录就是你目前所在的目录,可以通过cd命令来切换当前的工作目录。

    2.5Linux文件类型与扩展名:

    虽然在前面的2.2中的ls命令解释中解析过文件的类型,但只是从ls命令的角度解释了Linux文件的五个类型,即:- 、d、l、b、c,但实际上这五个分类还是一个比较宽泛的大类划分,下面基于这五个大类来了解文件类型更具体的划分:

    常规文件类型的具体划分,即ls命令[-]的文件类型的细分:

    1.纯文本文件(ASCLL):这是Linux系统中最多的一种文件类型,其文件内容是可以直接被人读懂的数据,例如数字、字母等。
    2.二进制文件(binary):二进制文件内容是只有系统认识的文件,Linux中可执行文件绝大部分都是这一种(scripts脚本文件不是二进制文件)。
    3.数据文件(data):它是一种特定格式的文件,一般用于被程序读写的文件,比如在Linux登入时就会将用户登入数据记录到/var/log/wtmp这个文件内,该文件就是一个数据文件。

    设备文件的具体划分,即ls命令[b、c]的文件类型的细分:

    与系统周边即存储等相关的一些文件,通常都集中存放在/dev这个目录下,设备文件有分类区块设备文件和字符设备文件。

    区块设备文件:用于存储数据,提供统一的存储接口的设备,比如硬盘、软盘等,在ls命令中标识为[b]的文件。

    字符设备文件:一些串行端口的接口设备,比如键盘、鼠标等设备,这些设备的特点就是一次性读取,不能截断输出,在ls命令中标识为[c]的文件。

    目录文件没有细分种类,它的文件内容就是记录文件列表,在ls命令中标识为[d]的文件。

    链接文件没有细分种类,它的文件内容就是记录了一个具体链接文件的目录,通过这个链接文件同样可以读写执行它链接的目标文件,在ls命令中标识为[l]的文件。

    下面是前面ls命令中没有提到的文件类型,即数据接口文件、数据传输文件。

    数据接口文件:这类文件常被用于网络上的数据交换,它的文件类型标识是[s]。

    数据传输文件:这类文件用来实现数据的传输,比如多个程序同时读写一个文件所造成的错误问题就是由FIFO设备实现的管道来解决,这类控制数据传输设备的文件类型标识是[p]。

    最后文件扩展名在Linux中没有什么实际意义,它不想再Windows中用扩展名来区分文件类型,虽然Linux本身好像不需要文件扩展名,但当Linux要进行网络交互的时候扩展名的存在还是有必要的,比如Linux作为服务器给网络上其他请按照非Linux系统设备提供文件资源;还有脚本或批处理文件本身就是文本文件,虽然没有扩展名也可以被执行,但如果有扩展名是不是更方便管理,例如shell写的脚本scripts文件就是.sh扩展名;还有针对不同压缩软件打包的压缩包需要对应的程序解压,有扩展名就会更方便处理,比如*Z、*.tar、*.tar.gz、*.zip、*.tgz等压缩包扩展名。

    2.6Linux文件名的长度限制及字符限制

    Linux传统文件系统ext和CentOS7的xfs文件系统下,文件名的最大长度都是255字节。

    Linux的文件名区分大小写,由于Linux在命令行模式下的一些命令操作,文件名最好避免以下这些特殊字符:

    * ? > < ; & ! [ ] | \ ' " ` ( ) { }

     三、Linux文件与目录管理

    3.1目录与路径

    关于Linux目录与路径的管理内容很简单,在前面的Linux操作系统(附二)1.3中有一些基础的介绍,这里再详细的介绍一下关于目录的切换、查看、新建、删除的相关命令的使用,在介绍这些命令的使用之前先了解一下一些特殊的目录:

    .    代表此层目录;
    ..   代表上一层目录;
    -    代表前一个工作目录;
    ~    代表目前用户身份所在的home目录;
    ~account    代表account这个用户的home目录;

    切换目录的命令【cd】

     cd [dir]  #dir表示要切换的路径,可以是特殊目录,也可以是绝对路径和相对路径,当不写[dir]时则表示回到当前用户的home目录下

    假设现在使用的时普通用户登入的,先使用su切换至root用户进入/root目录,然后接着下面的cd示例了解目录切换:

     su root  #执行然后使用root密码实现用户切换,实现用户切换之后当前的工作目录还是之前的普通用户home目录

     cd ~   #使用~特殊目录切换到/root目录下,也可以不传入[dir]即~直接使用cd切换到该目录

     su [username] #然后再切换至普通用户,当前工作目录还在/root

     cd      #直接使用cd进入普通用户的home目录下

     cd ..   #使用特殊目录..进入/home目录

     cd ../bin  #然后使用相对路径进入bin目录

     cd -    #然后再使用特殊目录-回到home目录下,注意连续使用cd -会在两个目录之间切换,而不会无限回退到某个历史工作目录

     cd ~[username]  #然后在使用特殊目录进入到指定用户的目录下

    查看当前工作目录的命令【pwd】

     pwd [-P]  #查看当前的工作目录,-P表示显示真正的目录,而非链式路径

    pwd是Print Working Directory的缩写,也就是显示目前所在的目录命令。

     pwd  #假设你当前再用户的home目录下,就会打印出当前用户的的home目录:/home/[username]

        #下面在/var/mail目录下测试pwd和pwd -P命令

     pwd  #打印结果:/var/mail

     pwd -P  #打印结果:/var/spool/mail,这是因为/var/mail是/var/spool/mail的链式路径

    新建目录的命令【mkdir】

     mkdir [-mp]  # -m选项表示设置文件权限; -p选项表示实现递归创建

    关于mkdir-m设置权限就是设置创建的目标权限对应的用户权限,设置参数方式采用权限的数值表示方式;关于-p实现递归创建目录就是可以创建多层目录,创建的多层目录采用路径字符串就可以实现,如果在某个路径下有多个同级目录使用"{}"包括起来,内部同级目录名使用","间隔,并且可以实现嵌套的方式创建。参考下面的示例来了解详细的使用:

     mkdir -m 711 test  #创建test目录并设置权限为:拥有者可读可写可执行,用户组成员和其他用户都只有可执行权限

     mkdir -p test1/test2/test3  #递归逐层创建test1、test2、test3目录

     mkdir -p a/{aa,ab/{aba,abb,abc},ac/{aca,acb}}  #递归逐层嵌套创建目录

    删除目录命令【rmdir】

     rmdir [-p]  #-p选项表示连同上一级空目录一起删除,并且带有递归效果,如果给定的路径上层没有其他数据都会一并删除

    如果想直接通过一个父级目录删除目录下的所有目录可以使用rm -r命令,不过需要注意的是这个命令会将目录下的所有数据删除(包括文件),下面来具体的示例:

     rmdir test  #删除当前目录下的test目录

     rmdir -p test1/test2/test3   #如果这些目录下没有多余的文件和目录test1,test2,test3都会被删除

     rmdir -p a/{aa,ab/{aba,abb,abc},ac/{aca,acb}}  #删除目录同样可以采用嵌套的方式实现

     rm -r a  #与上面的效果一致,但需要注意这个命令会删除a目录下面的所有数据,包括文件数据

    最后关于Linux下的目录与路径的一个知识点就是$PATH变量,关于什么是变量在之前的Linux操作系统(二)3.1中有提到过,如果有一些编程经验的非常容易理解这个是什么意思,如果不了解也没关系,只需要知道$PATH变量保存着当前工作区间工作必要的目录路径,比如命令是如何去哪里找,su命令切换后如何找到切换当前用户的home目录都在$PATH,可以使用下面的示例打印$PATH的值查看了解:

     echo $PATH  #打印结果:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/[username]/bin ,注意我将用户home目录名使用[username]替换了,这个是你当前的用户名。冒号“:”是用来分隔不同的路径的符号,没有特别含义。

    3.2文件与目录管理

    关于Linux文件与目录管理主要了解复制、删除、移动文件与目录的相关命令:cp、rm、mv,这些内容也没有神需要特别介绍的东西,下面直接进入命令语法和示例内容:

    复制文件或目录的命令【cp】

     cp [-adfilprsu] 源文件(source) 目标文件(destination)

     cp [options] source1 source2 source3 ... directory

    cp命令的选项参数解析:

    -a:相当于-dr --preserve=all的意思,至于dr请参考下列说明
    -d:若源文件为链接文件的属性(link file),则复制链接文件属性而非文件本身
    -f:为强制(force)的意思,若目标文件已经存在且无法开启,则删除后再尝试一次
    -i:若目标文件(destination)已经存在时,在覆盖时会先询问操作是否继续进行
    -l:进行硬链接(hard link)的链接文件建立,而非复制文件本身
    -p:连同文件的属性(权限、用户、时间)一起复制过去,而非使用默认属性
    -r:递归复制,用户目录的复制操作
    -s:复制成为符号链接文件(symbolic link),亦即“快捷方式”文件
    -u:destination比source旧才更新destination,或者destination不存在时才复制
    --preserve=all:除了-p的权限相关参数外,还加入SELinux的属性,links,xattr等也复制
    注:需要注意的是,如果源文件有两个以上,则最后一个目录文件一定要是“目录”才行

    需要注意的是,由于我们在复制文件时总希望复制到的数据最后是我们自己的,所以在默认条件下,cp的源文件与目标文件的权限是不同的,目标文件的拥有者通常会是命令操作者本身。然后需要注意的是-l、-p两个选项,-l只会生成一个链接文件,这个链接文件属于当前操作命令的用户,但链接文件本身并不拥有真实文件的数据,它只是作为一个链接指向源文件,这种操作也被称为硬链接;-p则是会将源文件原原本本的复制过来,其中包括文件的拥有者、群组、时间等权限属性,这种复杂通常也被称为软连接。

    关于硬链接和软链接会在后面的文件相关内容中详细介绍,下面进入cp命令的示例:

     cp ~/.bashrc /tmp/bashrc  #将当前用户home目录下的.bashrc复制到/tmp目录下并作为一个全新的文件bashrc

     cp -i ~/.bashrc /tmp/bashrc #这个复制操作会询问是否覆盖原来的文件,输入“y”然后回车键表示用当前的复制覆盖原来的文件,输入"n"表示不覆盖回车后结束操作

                  #其他的选项没有什么太多需要演示的,关于链接文件的复制后面在文件部分解析到了就明白了

    删除文件或目录的命令【rm】

     rm [-fir] 文件或目录

    rm的命令选项参数解析:

    -f:就是force的意思,忽略不存在的文件,不会出现警告信息
    -I:交互模式,在删除前会询问使用者是否继续操作
    -r:递归删除,这个选项需要注意,会将删除的目录下所有文件全部删除

    关于这个命令的解析也是没有必要的,在之前的目录删除中就演示过-r选项操作,这里就演示一下将/tmp/bashrc删除:

     rm /tmp/bashrc  #注意这个操作只会删除bashrc这个文件,而不会对tmp进行操作,并且-r的递归也是向指定的目录往其子目录进行删除操作

    移动文件或目录的命令【mv】

     mv [-fiu] 源文件(source) 目标文件(destination)

     mv [options] source1 source2 source3 ... dirctory

    mv命令的选线参数解析:

    -f:force强制的意思,如果目标文件已经存在,不会询问而直接覆盖
    -i:若目标文件已经存在,就会询问是否覆盖
    -u:若目标文件已经存在,且源文件比较新,才会更新

    关于文件移动文件或目录需要注意的是它可以通过目标文件来修改文件名,但不会修改文件的其他特性,比如不会修改文件权限。参考示例:

     mv ./a /tmp/b  #将当前目录下的a文件移动到tmp目录下,并改名为b

    最后关于文件与目录管理还有两个命令就是获取文件名和目录名,每个路径都由两个部分组成:目录名、文件名,最右侧的一个路径节点名称就是文件名,该文件名的左侧路径部分就是目录名,分别可以通过dirname、basename两个命令来获取,关于这部分内容在之前的Linux操作系统(附二)1.3中就有介绍和相关示例,可以参考之前的博客内容。

    3.3文件内容查看

    查看文件内容包括查看文件的数据内容和属性内容,在前面已经介绍过通过ls命令来查看文件的相关属性内容,这里主要介绍如何查看文件数据内容,查看文件数据内容的命令主要有8个命令,这8个命令又可以分为四个功能类型,分别是:一、查看全部文件数据cat、tac、nl;二、可以根据当前屏幕可打印的容量分页查看文件内容more、less;三、截取部分文件内容查看head、tail;四、以二进制的方式读取文件内容od。由于这部分内容过于简单,会省略一些示例代码。

    从第一行开始查看文件全部内容【cat】

     cat [-AbEnTv] 文件

    cat命令的选项参数解析:

    -A:相当于-vET的整合选项,可列出一些特殊字符而不是空白而已。
    -b:列出行号,针对非空白字行做行号显示,空白行不标行号。
    -E:将结尾的换行符$显示出来。
    -n:打印出行号,两桶空白字符也会有行号,与-b的选项不同。
    -T:将[tab]按键以^I显示出来。因为这种特殊字符不用指定方式先显示就是空白,无法与真正的空白字符区分。
    -v:列出一些看不出来的特殊字符,原有同上。

    从最后一行开始查看文件全部内容【tac】

     tac [-brs] 文件

    tac本质上就是cat命令的一个反向读取操作,他们都是逐行读取,但命令的选项差异还是比较大。

    -b:将分隔符放在前面而不是后面
    -r:将分隔符解析为正则表达式
    -s:使用STRING作为分隔符,而不是换行符

    从第一行开始查看文件内容并同时显示行号【nl】

     nl [-bnw] 文件

    nl的默认方式与cat -n是一样的,但nl通过选项增加了一些行号的格式,下面来看nl的选项解析:

    -b:指定行号的指定方式,主要有两种:
        -b a:表示不论是否为空行,也同样列出行号
        -b t:如果有空行,空的那一行不列出行号
    -n:列出行号的表示方法,主要有三种:
        -n ln:行号在屏幕的最左方显示
        -n rn:行号在屏幕的最右方显示,且不加0
        -n rz:行号在自己栏位的最右方显示,且加0
    -w:行号栏位的占用的字符数

    翻页查看和检索文件内容的命令【more】

     more [-dlfpcsu] [-num] [+/pattern] [+linenum] [file ...]

    一般使用more查看文件不怎么会用到选项,但还是做一些介绍,重点关注后面通过按键来配合more查看文件:

    -num:该选项指定一个整数,即屏幕大小(以行为单位)。
    -d:more将提示用户“[按空格键继续,' q '键退出。)”,并将显示“[按“h”键查看指示。而不是在非法钥匙被打开时按铃按下。
    -l:通常将^L(换页符)作为一个特殊字符,并在任何行之后暂停包含表单提要。l选项将防止这种行为。
    -f:导致更多的逻辑行计数,而不是屏幕行(即,长行不会折叠)。
    -p:不滚动。相反,清空整个屏幕,然后显示文本。
    -c:不滚动。相反,应该从屏幕顶部开始绘制,清除每一行的剩余部分
    -s:将多个空行压缩成一行。
    -u:抑制凸显。
    +/pattern选项指定在每个文件显示之前要搜索的字符串。
    +linenum从行号num开始。
    

    关于more的按键交互式查看文件内容的按键解析:

    空格间:代表向下翻页;
    Enter(回车键):代表向下翻一行;
    /字符串:表示在这个显示的内容当中,向下查找字符串这个关键字(检索)
    :f:显示出文件名以及目前显示的行数;
    q:表示退出more,不再显示该文件内容;
    b或[ctrl] -b:代表往回翻页,不过这个操作只对文件有用,对管道五用。

    翻页查看和检索文件内容的命令【less】:

     less 文件  #关于less命令的选项非常丰富,这里考虑篇幅问题,这里仅介绍一些常用的按键交互内容

    关于less命令查看文件内容的常用交互按键:

    空格间:向下翻动一页;
    [pagedown]:向下翻动一页;
    [pageup]:向上翻动一页;
    /字符串:向下查找字符串的功能;
    ?字符串:向上查找字符串的功能;
    n:重复前一次查找;
    N:反向的重复前一次查找;
    g:前进到这个数据的第一行;
    G:前进到这个数据的最后一行;
    q:离开less这个程序;

    只查看文件前几行内容【head】

     head [-n number] 文件

    关于head命令的选项解析:

    -n:表示显示几行的意思,即语法中的number

    只查看文件后几行内容【tail】:

     tail [-n number] 文件

    关于tail命令的选项解析:

    -n:表示显示几行的意思,即语法中的number
    -f:表示持续刷新显示后面所接文件中的内容,可以使用[ctrl]-c可以结束刷新

    以二进制的方式查看文件内容【od】

     od [-t TYPE] 文件

    od命令的选项及相关参数解析:

    -t:后面可以接各种类型的输出(TYPE),例如:
        a:使用默认的字符输出;
        c:使用ASCII字符输出;
        d[size]:使用十进制来输出;
        f[size]:使用浮点数值输出;
        o[size]:使用八进制来输出;
        x[size]:使用十六进制来输出;

    3.4查看文件的时间

    这个内容其实在前面第一节介绍ls命令的时候就已经包含了相关的内容,只是没有特别一出来解析,关于文件时间实际上包含三个时间分别是:

    修改时间(modification time, 简写mtime):当文件内容数据发生变化时,该文件时间会被更新。
    状态时间(status time, 简写ctime):当文件的状态发生改变时,这个文件时间会被更新,比如文件的权限与属性发生改变时,这个时间就会更新。
    读取时间(access time, atime):当文件被读取时,这个文件时间会被更新,比如使用cat读取一个文件,这个文件时间就会更新。

    查看文件信息并指定查看文件某个时间数据的命令【ll】

    通常情况下使用ls查看文件所打印的时间是文件的修改时间,即mtime,例如:

     cp -a ~/.bashrc /tmp/bashrc

     cd /tmp

     date; ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc

     #打印结果:

     Fri Jun  3 11:19:15 PDT 2022
    -rw-r--r--. 1 tx tx 124 Jul 18  2013 bashrc
    -rw-r--r--. 1 tx tx 124 Jun  3 11:18 bashrc
    -rw-r--r--. 1 tx tx 124 Jun  3 11:18 bashrc

    关于 ll 命令本质是ls -l,ll只是ls -l的命令别面,关于什么是命令别面会在后面的bash相关内容中介绍,然后就是采用分号“;”间隔命令可以实现多个命令串行执行。

    根据打印结果会发现mtime发生了改变,这是因为复制采用-a选项实现了创建一个全新的文件,所以文件内容的修改时间就是最新的时间,而文件的状态时间和读取时间并未发生改变。

    通过touch命令修改指定修改文件的某个时间:

     touch [-acdmt] 文件

    touch命令的选项解析:

    -a:仅修改access time为当前时间,即atime;
    -c:仅修改status time为当前时间,即ctime;
    -d:后面可以接自定义的日期,也可以使用--date="日期或时间"
    -m:仅修改modification time为当前时间,即mtime;
    -t:后面可以接自定义的时间,格式为[YYYYMMDDhhmm]

    touch的示例:

     touch -d "2 days ago" bashrc

     touch -t 202206030000 bashrc

    3.5文件与目录的默认权限与隐藏权限

    关于文件与目录的权限在前面的第二节中就有介绍,前面主要介绍了用户与文件的权限关系与相关命令,但在一般情况下创建文件的时候其初始权限是什么呢?当然创建文件的时候可以自定义文件权限,但如果没有自定呢?

    当创建文件是没有自定义权限的化就会使用当前目录下的默认权限,可以通过umask命令来实现默认命令的查看与设置:

    查看和设置当前目录下默认权限的命令【umask】

     umask [-pS] [mode]  

    当umask不使用mode参数时就是查看当前目录下的默认,-p是输出一种可以重复输入使用的值;如果-p用于设置,设置成功的话则返回0;-S则是使用“user=***”格式逐个输出各个用户的权限;默认情况不适用任何参数umask则是输出,输出当前目录下的默认权限的掩码,即使用mode的八进制值最大值减去当前目录的真实的mode值,比如当前目录的默认权限是“rwxrwxr-x”,它的mode值应该是775,那么它的mode掩码则是002。

     umask -p  #umask 0002

     umask -S    #u=rwx,g=rwx,o=rx

     umask      #0002

    当你看到umsk打印的居然是四位数时,一开始肯定是满脸的疑惑,为什么不是我前面是讲的002,这就涉及到了一个非常重要的内容,那就是特殊权限,在了解特殊权限之前你只需要知道在0002中后三位002就是前面提到的[用户、群组、普通用户]的权限掩码,第一位0表示的就是特殊权限的掩码。

    文件的特殊权限:SUID、SGID、SBIT

    关于特殊权限先来看一个案例,假设普通用户需要修改自己的密码,系统用户账户密码存储在/etc/shadow这个文件上,而该文件的权限是[----------. 1 root root],也就是说这个文件只有root用户拥有修改权限,那普通用户是如何实现修改密码这个操作的呢?这就要追述到实际操作修改/etc/shadow文件的并不用户本人,而是中间还有一个实现修改操作的程序文件,这个程序文件就是/usr/bin/passwd,这时候问题就来了即便操作一个程序去实现修改也还是这个用户呀,没错,还是这个用户,这其中的关键就在于普通用户指定的/usr/bin/passwd这个程序文件的权限,下面我们来查看一下这个文件的权限设置:

     ls -al /usr/bin/passwd  #执行打印结果:-rwsr-xr-x. 1 root root 30768 Feb 22  2012 /usr/bin/passwd

    作为普通用户拥有对passwd的执行权限,这并不能解释为什么普通用户就可以通过这个程序实现对shadow的写操作,再来看passwd的拥有者权限,即root对passwd的权限是[rws],root用户这个执行权限是[s]这在前面的文件用户权限介绍中没有提到过的,这里暂时提一下这个s权限就是set UID即SUID权限,也是因为这个权限普通用户执行这个程序文件passwd才具备了修改shadow的权限,那么接下来就来了解这个权限的真正含义:

    SUID权限(Set UID)的限制与功能

    SUID权限仅对二进制程序有效;
    执行者对于该程序需要具有X的可执行权限;
    本权限仅在执行该程序的过程中有效;
    执行者将具备该程序拥有者的权限;

    通过这个解释可能还不能SUID权限如何实现,一个二进制程序文件要实现SUID的权限,需要在用户组和其他用户权限上设置可执行(X)权限,然后在文件拥有者即用户权限设置可执行权限为[s],当用户组和其他用户执行该文件时就会同时拥有当前执行文件拥者的权限,相当于时文件拥有者通过可执行权限[s]将自己的权限授权给用户组和其他用户,这时候用户组和其他用户执行该程序文件时就可以带着当前可执行文件拥有者的身份权限,去操作这个可执行文件拥有者可以操作的其他文件。

    比如前面的例子中,普通用户执行passwd时通过root的s可执行权限就拥有了root用户身份的权限,他就可以实现对shadow文件的写操作,因为root用户对shadow文件拥有可写的权限。

    SUID的权限mode数值是4,但这个权限不体现在用户权限mode值上,而是体现再文件的特殊权限上,在前面的umask命令中就是四位mode掩码的第一位,所以对umask的特殊权限依然采用的是掩码方式打印,有了对SUID的了解再来理解SGID和SBIT就很容易了:

    SGID权限(Set GID)的限制与功能

    SGID对二进制程序有用;
    程序执行者对于改程序来说,需具备x的权限;
    执行者在执行的过程中将会获得该程序用户组的支持;

    SGID权限获得权限的依然是可执行该文件的用户,执行该程序文件的用户可以获得该文件的用户组的权限,也就是说与SUID对比授权方由所有者变成了GUID的用户组。

    SBIT权限(Sticky Bit)的限制与功能

    SBIT目前只针对目录有效,对于文件没有效果;
    当用户对于此目录具有w、x权限,即具有写入和执行的权限;
    当用户在该目录下建立文件或目录时,仅自己与root才有权力删除该文件;

    SBIT权限可以让拥有可执行和可写入的其他用户,获得一个目录下用户组自身权限的可写入权限,而不能对当前目录下非用户组文件执行写入权限,即不能对当前目录所有者独有的文件进行修改和删除操作。

    关于特殊权在后面的Linux使用者管理相关博客中还会有详细的介绍,这里算是一个初步的了解。

    3.6文件隐藏属性

    关于文件的隐藏属性只对Linux传统的ext2、ext3、ext4文件系统有作用,但在CentOS7中使用的默认文件系统xfs没有支持隐藏属性的chattr命令,xfs2也仅仅支持chattr部分特性,关于文件系统制在下一篇博客中就会有介绍,这里你只需要知道文件隐藏属性的作用范围即可。

    关于文件隐藏属性有两个命令,一个是chattr命令用来配置文件隐藏属性,另一个是lsattr命令用来查看文件隐藏属性,下面进入文件隐藏属性的语法和选项的介绍:

    配置文件隐藏属性的命令【chattr】

     chattr [+-=] [ASacdistu] 文件或目录名称

    chattr命令的选项及参数解析:

    +:增加某一个特殊参数;
    -:删除某一个特殊参数;
    =:直接设置参数,且仅有后面的参数;
    A:当设置了A这个属性时,读取此文件atime将不会被修改(结合3.4的内容),可避免I/O较慢的机器过度读写磁盘;
    S:一般情况下文件是非同步写入的,如果加上这个属性就会在每次修改时都实现同步写入;
    a:当设置a之后,这个文件只能增加数据,不能删除也不能修改数据,只有root才能设置这个属性;
    c:设置这个属性之后,将会自动将此文件压缩,读取时会自动解压,但在存储时,会先进行压缩再存储。
    d:当ump程序执行的时候,这是d属性将可以使该文件不会被dump备份;
    i:可以实现文件不能被删除、改名、设置链接也无法写入或新增数据,只有root能设置这个属性;
    s:可以实现当文件被删除时,它将会被从硬盘上彻底删除,所以如果误删就无法恢复;
    u:与s相反,如果文件被删除了,数据还会存在硬盘上,可以用来删除后实现恢复文件。

    在xfs2文件系统中chattr命令支持[AadiS]这些部分属性,下面用设置一个i隐藏属性来作为示例:

     su root  #切换至root用户

     touch attrtest  #创建一个文件

     chattr +i attrtest  #添加i属性

     rm attrtest  #尝试删除attrtest-->remove regular empty file `attrtest'? y-->cannot remove `attrtest': Operation not permitted

     chattr -i attrtest  #删除i属性

     rm attrtest  #再次尝试删除attrtest->remove regular empty file `attrtest'? y-->删除成功

    查看文件隐藏属性的命令【lsattr】:

     lsattr [-adR] 文件或目录

    lsattr命令的选项及参数解析:

    -a:隐藏文件的属性也显示出来
    -d:如果接的是目录,仅列出目录本身的属性而非目录内的文件名
    -R:连同子目录的数据也一并列出来

     3.7命令与文件的查找

    查找命令执行文件路径的命令【which】

    which这个命令是根据$PATH这个bash变量去查找执行文件的目录的路径名,关于$PATH包含哪些可执行文件名路径可以使用echo命令打印$PATH的值就知道了,结合 Linux操作系统(附二)1.5、2.x的相关内容了解。

     which [-a] [--skip-alias which] command  #选项a可以将查找的命令所有可执行文件路径打印出来,如果不使用这个选项就只打印查找到的第一个可执行文件路径

    下面通过which来尝试查找which自己的命令可执行文件路径:

     which -a which

     #打印结果:

     alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
       /usr/bin/which
     /usr/bin/which

    通过打印结果可以看到which有两个可执行文件路径,为什么一个命令会有两个甚至多个可执行文件呢?这是因为命令别名它也是一个可执行文件,但是这里打印的路径都是一样的是因为这个命令别名采用了硬链接的方式(推测),在有的CentOS版本中可能会有一个/bin/alias的路径(实际上就是这里的alias),关于命令别面的内容会在后面的bash相关内容中详细介绍,还有就是which不能查找內置命令的路径(例如cd这个命令,相关内容暂时可以参考:Linux操作系统(附二)1.5),因为內置命令根本就没有可执行文件,它的可执行程序內置在Shell程序内部,关于这方面的内容都会在bash相关内容中介绍。

    关于--skip-alias which这个选项可以用来忽略别面,从而实现查找到命令的真正可执行文件路径,这个可以自己尝试看看它的查询结果。

    查找特定目录中的文件路径【whereis】

    这个命令在man命令文档中的介绍是查找二进制、源文件、说明文件manual路径下的文件,这么解释可能还是不太能理解它真正的查找范围,whereis命令书主要是针对/bin/sbin下面的可执行文件、/usr/share/man下面的man page文件来查找命令的路径,所以whereis会相对which基于$PATH的查找所涵盖的命令更多一些,下面介绍一些whereis命令的语法及相关选项:

     whereis [-bmsu] 文件名或目录名

    whereis命令选项解析:

    -l:可以列出whereis会查找的几个主要目录;
    -d:之查找二进制(binary)格式的文件;
    -m:只查找说明文件manual路径下的文件;
    -s:只查找源文件(source);
    -u:查找不在上述三个项目当中的其他特殊文件;

    whereis是用来查找特定文件的命令,那为什么可以查找命令可执行文件路径呢?这是因为在Linux系统中命令名称其实就是命令对应可执行文件的名称,而whereis所查找的这些特定目录中主要就是与命令相关的文件。最后使用whereis演示查找ifconfig这个命令的路径:

     whereis ifconfig  #打印结果:ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz

    根据/var/lib/mlocate内的数据库记录,查找用户输入关键词的文件路径【locate】

    既然是查找文件路径,而且还是基于一个数据库的数据记录来查找,那么就有必要了解这个数据会记录什么数据,这么来说mlocate就是一个数据库,它会事先对磁盘的文件进行扫描,然后将扫描到的文件名和路径记录到这个数据,locate就是由这个数据提供的数据查询接口命令,并且可以通过文件名的部分字段进行模糊查询来获取可能对应的文件路径。但是需要注意的是这个数据库扫描它不是时实的,所以可能存在查找不到数据的可能性,这里先来了解locate命令的语法:

     locate [-ir] keyword

    locate命令的选项解析:

    -i:忽略大小写的差异;
    -r:可以使用正则表达式作为查询参数keyword,进行匹配文件名查找
    -c:不输出文件名,仅计算找到的文件数量;
    -l:仅输出几行的意思,例如输出五行则是locate -l 5 keyword;
    -S:输出locate所使用的数据库文件的相关信息,包括该数据库记录的文件/目录数量等;

    这个命令的具体演示应该就没有必要了,这里我想介绍一个与locate和mlocate数据库相关的另一个命令,这个命令就是updatedb,这个命令可以用来更新mlocate数据库文件。

    更新/var/lib/mlocate内的数据库文件的命令【updatedb】

     updatedb [-fneUhol]

    这个命令在后面的文件系统管理中还会有涉及,这里只需要知道这个命令可以用来更新mlocate数据库就可以了,可以不使用任何选项执行这个命令对数据库文件进行更新,这个过程需要一些时间,因为需要遍历系统目录树。

    查找文件路径的命令【find】

     find [PATH] [option] [action]

    这个命令查找文件是对整个磁盘的文件进行遍历查找,PATH用来指定查找的路径(也就是在这个指定的路径下查找出所有符合条件的文件),这个过程非常耗时,好在可以通过选项和选项参数action进行条件查找,下面就来具体的介绍一下find的选项及action的详细内容:

    1.与时间相关的选项:-atime、-ctime、-mtime(还记得前面的文件时间属性吧,就是3.4中的内容),这里以-mtime来说明:
        -mtime n:n为数字,表示在n天之前的一天内被修改过内容的文件;
        -mtime +n:表示在n天之前(不含n天本身)被修改过内容的文件;
        -mtime -n:表示在n天之内(含n天本身)被修改过内容的文件;
        -newer file:file表示一个存在的文件,列出比file还新的文件;
    2.与使用者或用户组名称有关的选项:
        -uid n:n为数字,这个数字是使用者的账号ID,表示查找属于这个用户的文件;
        -gid n:n为数字,这个数字是用户组名称的ID,表示查找属于这个用户组的文件;
        -user name:name为用户名称,表示查找这个用户的文件;
        -group name:name为用户组名称,表示查找这个用户组的文件;
        -nouser:表示查找拥有者不在/etc/passwd中的文件,也就是说查找非系统用户的文件;
        -nogroup:表示查找用户组不在/etc/group中的文件,也就是说查找非系统用户组的文件;
    3.与文件权限及名称有关的选项:
        -name filename:查找文件名为filename的文件;
        -size [+-]SIZE:查找比SIZE还要大(+)或小(-)的文件,SISE需要带单位c表示Bytes、k表示1024Bytes。例如【-szie +50k】就是查找比50KB还要大的文件;
        -type TYPE:表示查找文件类型为TYPE的文件,关于文件类型参考2.2的内容,例如【-type l】就是查找文件类型为链接文件
        -perm mode:查找文件权限为mode的文件
        -perm -mode:查找文件权限必须涵盖mode权限的文件
        -perm /mode:查找文件权限mode权限包含的权限的文件,比如【-perm /755】可以查找到权限为-rw-------的文件,这是因为775权限里面包含了600的权限
    4.额外的选项:
        -exec command:表示使用command来处理查询结果,比如【-perm /7000 -exec ls -l {} \;】表示查找权限为7000所包含的权限的文件,并使用ls -l命令来获得这些文件的属性与权限数据;这里有一些关键字需要解释一下:{}表示find的查询结果、\表示转义、\;表示-exec到这里结束,因为;在bash环境下有特殊意义。

    最后写一个find命令的演示表示一下,用来更直观的了解find语法:

     find /etc -name '*httpd*'  #*表示通配符,这行命令表示查找etc下的名称为*httpd*的文件

     find /usr/bin /usr/sbin -perm /6000 #表示查找这两个目录下的权限6000所包含的权限的文件

     find /etc -newer /etc/passwd  #表示查找比passwd还新的文件

     find / -mtime 0   #表示查找从当前时间还是计算往前的24小时之内修改过的文件

  • 相关阅读:
    KMP
    837B. Balanced Substring
    JDK7和JDK8新特性
    数据库索引的实现原理
    mysql索引总结----mysql 索引类型以及创建
    Java 8新特性终极指南
    类加载机制
    类加载过程
    深入理解java虚拟机 精华总结(面试)(转)
    几种常用的设计模式介绍(转)
  • 原文地址:https://www.cnblogs.com/ZheOneAndOnly/p/16256350.html
Copyright © 2020-2023  润新知