第六章 Linux文件与目录管理

一、目录与路径

1.绝对路径:路径的写法一定由根目录/写起;

相对目录:路径写法不是由/写起。相对路径指相对于目前工作目录的路径。

2.目录的相关操作

在Linux下,根目录下没有上层目录存在。

符号/命令含义
.代表此目录
..上级目录
-前一个工作目录
~account代表“account”用户的主文件夹

 

命令含义使用方式
cd变换目录cd [相对路径或者绝对路径]
pwd显示当前目录pwd [-P](-P:显示出当前的路径,而非使用连接路径)
mkdir新建一个目录mkdir [-mp] 目录名称(-m:配置文件夹的权限;-p递归建立层级目录)
rmdir删除一个目录rmdir [-p] 目录名称(-p:连同上层“空”目录一起删除)

[root@study ~]# cd ~dmtsai

# 代表去到 dmtsai 这个用户的主目录,亦即 /home/dmtsai

[root@study dmtsai]# cd ~

# 表示回到自己的主目录,亦即是 /root 这个目录

[root@study ~]# cd

# 没有加上任何路径,也还是代表回到自己主目录的意思喔!

[root@study ~]# cd ..

# 表示去到目前的上层目录,亦即是 /root 的上层目录的意思;

[root@study /]# cd -

# 表示回到刚刚的那个目录,也就是 /root ~

 

范例:单纯显示出目前的工作目录:[root@study ~]# pwd/root   <== 显示出目录啦~范例:显示出实际的工作目录,而非连接文件本身的目录名而已[root@study ~]# cd /var/mail   <==注意,/var/mail是一个连接文件[root@study mail]# pwd/var/mail         <==列出目前的工作目录[root@study mail]# pwd -P/var/spool/mail   <==怎么回事?有没有加 -P 差很多~[root@study mail]# ls -ld /var/maillrwxrwxrwx. 1 root root 10 May  4 17:51 /var/mail -> spool/mail# 看到这里应该知道为啥了吧?因为 /var/mail 是连接文件,连接到 /var/spool/mail。所以,加上 pwd -P 的选项后,会不以连结文件的数据显示,而是显示正确的完整路径!

 

[root@study tmp]# mkdir test    <==建立一名为 test 的新目录[root@study tmp]# mkdir test1/test2/test3/test4mkdir: cannot create directory ‘test1/test2/test3/test4’: No such file or directory[root@study tmp]# mkdir -p test1/test2/test3/test4#加了这个-p的选项,可以自行帮你建立多层目录!范例:建立权限为rwx--x--x的目录[root@study tmp]# mkdir -m 711 test2

3.关于执行文件路径的变量:$PATH

执行命令echo $PATH看哪些目录被定义出来了。注意echo有“显示”的意思,PATH前面的$表示后面接的是变量。

图1.1 $PATH变量内容

PATH这个变量的内容是由一堆目录所组成的,每个目录中间用冒号(:)来隔开,每个目录是有顺序之分的。

例题1::假设你是root,如果你将ls由/bin/ls移动成为/root/ls(可用「mv/bin/ls/root」指令达成),然后你自己本身也在/ root目录下,请问(1)你能不能直接输入ls来执行?(2)若不能,你该如何执行ls这个指令?(3)若要直接输入ls即可执行,又该如何进行?

答案:(1)不能。因为/root这个目录并没有被添加到PATH中去,所以即使你在/root目录下也无法搜索到ls这个命令。

(2)使用绝对路径或者相对路径来执行这个命令:/root/ls(绝对路径)、./ls(相对路径)。

(3)将当前目录加入到PATH中去。执行PATH=”${PATH}:/root”

 

例题2:为什么 ${PATH} 搜寻的目录不加入本目录(.)?

答案:如果在PATH中加入本目录(.)后,确实我们就能够在指令所在目录进行指令的执行了。但是由于你的工作目录并非固定(常常会使用cd来切换到不同的目录), 因此能够执行的指令会有变动,这对用户来说并非好事。

另外,如果有用户在/tmp底下做了一个指令,因为/tmp是大家都能够写入的环境,所以他当然可以这样做。假设该指令可能会窃取用户的一些资料,如果你使用root的身份来执行这个指令,那不是很糟糕?如果这个指令的名称又是经常会被用到的ls时,那『中标』的机率就更高了!

所以,为了安全起见,不建议将『.』加入PATH的搜寻目录中

由此我们可以得到以下结论:

(1)不同身份用户预设的PATH不同,预设能够随意执行的指令也不同;

(2)相同的指令,${PATH}中哪个目录首先被查询,就执行哪个目录下的指令;

(3)PATH是可以修改的;

(4)使用绝对路径或相对路径直接指定某个指令的文件名来执行,会比搜寻PATH来的正确;

(5)指令应该要放置到正确的目录下,执行才会比较方便;

(6)本目录(.)最好不要放到PATH当中。

二、文件与目录管理

1.查看文件与目录:ls

默认仅显示:非隐藏文件的文件名以文件名进行排序文件名代表的颜色显示

[root@study ~]# ls [-aAdfFhilnrRSt] 文件名或目录名称[root@study ~]# ls [--color={never,auto,always}] 文件名或目录名称[root@study ~]# ls [--full-time] 文件名或目录名称选项与参数:-a  :全部的文件,连同隐藏档( 开头为 . 的文件) 一起列出来(常用)-A  :全部的文件,连同隐藏档,但不包括 . 与 .. 这两个目录-d  :仅列出目录本身,而不是列出目录内的文件数据(常用)-f  :直接列出结果,而不进行排序 (ls 预设会以文件名排序!)-F  :根据文件、目录等信息,给予附加数据结构,例如:      *:代表可执行文件; /:代表目录; =:代表 socket 文件; |:代表 FIFO 文件;-h  :将文件容量以人类较易读的方式(例如 GB, KB 等等)列出来;-i  :列出 inode 号码,inode 的意义下一章将会介绍;-l  :长数据串行出,包含文件的属性与权限等等数据;(常用)-n  :列出 UID 与 GID 而非用户与用户组的名称 (UID与GID会在账号管理提到!)-r  :将排序结果反向输出,例如:原本文件名由小到大,反向则为由大到小;-R  :连同子目录内容一起列出来,等于该目录下的所有文件都会显示出来;-S  :以文件容量大小排序,而不是用文件名排序;-t  :依时间排序,而不是用文件名。--color=never  :不要依据文件特性给予颜色显示;--color=always :显示颜色--color=auto   :让系统自行依据设定来判断是否给予颜色--full-time    :以完整时间模式 (包含年、月、日、时、分) 输出--time={atime,ctime} :输出 access 时间或改变权限属性时间 (ctime)                        而非内容变更时间 (modification time)

2.复制、删除与移动:cp、rm、mv0

(1)cp:复制、建立快捷方式、对比文件的新旧而予以更新,复制整个目录。

[root@study ~]# cp [-adfilprsu] 来源文件(source) 目标文件(destination)[root@study ~]# cp [options] source1 source2 source3 .... directory选项与参数:-a  :相当于 -dr --preserve=all 的意思,至于 dr 请参考下列说明;(常用)-d  :若来源文件为连接文件的属性(快捷方式),则复制连接文件属性而非文件本身;-f  :为强制(force)的意思,若目标文件已经存在且无法开启,则移除后再尝试一次;-i  :若目标文件(destination)已经存在时,在覆盖时会先询问动作的进行(常用)-l  :进行硬连接(hard link)的连结文件建立,而非复制文件本身;-p  :连同文件的属性(权限、用户、时间)一起复制过去,而非使用默认属性(备份常用)-r  :递归持续复制,用于目录的复制行为;(常用)-s  :复制成为符号连接文件 (symbolic link),也就是快捷方式;-u  :destination比source旧才更新destination,或destination不存在的情况下才复制。--preserve=all:除了-p权限相关参数,还加入SELinux的属性, links, xattr等也复制了。

注意:

①如果来源档有两个以上,则最后一个目的文件一定要是目录才行!

②不同身份者执行这个指令会有不同的结果,特别是-a/-p选项。

③在预设条件中,cp的来源文件和目的文件的权限是不同的,目的文件的拥有者通常会是指令操作者本身。

④如果没有加上任何选项,cp复制的是源文件,而非连接文件属性。

(2)mv:移动目录与文件,更名。

[root@study ~]# mv [-fiu] source destination[root@study ~]# mv [options] source1 source2 source3 .... directory选项与参数:-f  :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;-i  :若目标文件 (destination) 已经存在时,就会询问是否覆盖!-u  :若目标文件已经存在,且 source 比较新,才会更新 (update)

 

范例一:复制一文件,建立一目录,将文件移动到目录中[root@study tmp]# mkdir mvtest[root@study tmp]# mv bashrc mvtest# 将某个文件移动到某个目录去,就是这样做!范例二:将刚刚的目录名称更名为 mvtest2[root@study tmp]# mv mvtest mvtest2 <== 这样就更名了!简单~# 其实在 Linux 底下还有个有趣的指令,名称为 rename ,该指令专职进行多个文件名的同时更名,并非针对单一文件名变更,与mv不同。请man rename。范例三:再建立两个文件,再全部移动到 /tmp/mvtest2 当中[root@study tmp]# cp ~/.bashrc bashrc1[root@study tmp]# cp ~/.bashrc bashrc2[root@study tmp]# mv bashrc1 bashrc2 mvtest2# 注意到这边,如果有多个来源文件或目录,则最后一个目标文件一定是『目录!』# 意思是说,将所有的数据移动到该目录的意思!

 

(3)rm:移除文件

[root@study ~]# rm [-fir] 文件或目录选项与参数:-f:就是force的意思,忽略不存在的文件,不会出现警告讯息;-i:互动模式,在删除前会询问用户是否动作-r:递归删除啊!最常用在目录的删除了!这是非常危险的选项!!!

注意:如果我们要删除以“-”开头的文件,由于“-”会被认为是选项的前缀,所以删除的时候可以使用前面添加当前目录的方式进行。例如要删除“-aaa”文件,我们可以输入“rm ./-aaa”。

3.取得路径的文件名与目录名称

[root@study ~]# basename /etc/sysconfig/networknetwork         <== 很简单!就取得最后的文件名~[root@study ~]# dirname /etc/sysconfig/network/etc/sysconfig  <== 取得的变成目录名了!

三、文件内容查阅

常用命令及其作用如下表所示。

命令作用命令作用
cat由第一行开始显示文件内容more一页一页地显示文件内容
tac从最后一行开始显示head只看头几行
nl显示的时候,顺便输出行号tail只看结尾几行
less与more类似,但是它可以往前翻页od以二进制方式读取文件内容

1.cat(concatenate,串联)

[root@study ~]# cat [-AbEnTv]选项与参数:-A  :相当于 -vET 的整合选项,可列出一些特殊字符而不是空白而已;-b  :列出行号,仅针对非空白行做行号显示,空白行不标行号!-E  :将结尾的断行字符 $ 显示出来;-n  :打印出行号,连同空白行也会有行号,与 -b 的选项不同;-T  :将 [tab] 按键以 ^I 显示出来;-v  :列出一些看不出来的特殊字符

2.tac(反向列显)

由最后一行到第一行反向显示在屏幕上。

3.nl(添加行号打印)

[root@study ~]# nl [-bnw] 文件选项与参数:-b  :指定行号指定的方式,主要有两种:      -b a :表示不论是否为空行,也同样列出行号(类似 cat -n);      -b t :如果有空行,空的那一行不要列出行号(默认值);-n  :列出行号表示的方法,主要有三种:      -n ln :行号在屏幕的最左方显示;      -n rn :行号在自己字段的最右方显示,且不加 0 ;      -n rz :行号在自己字段的最右方显示,且加 0 ;-w  :行号字段的占用的字符数。

上面提到的命令都是一次性将数据显示在屏幕上面。

4.more(一页一页翻动)

使用格式:

more [文件名]

more运行过程中的按键及作用:

命令作用命令作用
空格键向下翻一页:f立刻显示出文件名及目前显示的行数
Enter向下翻一行q代表立刻离开more,不再显示该文件内容
/字符串显示的内容中,向下搜寻“字符串”关键词b或ctrl+b代表往回翻页,只对文件有用,对管道无用。

5.less(一页一页翻动)

使用格式:

less [文件名]

命令作用命令作用
空格键向下翻一页n重复前一个搜寻
[pagedown]向下翻一页N反向的重复前一个搜寻
[pageup]向上翻一页g前进到这个数据的第一行去
/字符串向下搜寻“字符串”G前进道这个数据的最后一行去
?字符串向上搜寻“字符串”q退出less

注意:man指令就是调用less来显示说明文件的内容

我们可以将输出的数据做一个最简单的选取,那就是取出前面(head)几行或者后面(tail)几行文字的功能。注意:headtail都是以行为单位进行数据选取的

6.head(取出前面几行)

[root@study ~]# head [-n number] 文件名选项与参数:-n  :后面接数字,代表显示几行的意思。预设为10行。

若后面接的数字为负数,则代表列出前面所有行数,但不包括后面的行数。例如-100,就代表不列出最后100行。

7.tail(取出后面几行)

[root@study ~]# tail [-n number] 文件名 选项与参数:-n  :后面接数字,代表显示几行的意思。默认显示最后10行。-f  :表示持续侦测后面所接的文件名,要等到按下[ctrl]-c才会结束tail的检测

若只想列出前面m行以后的数据,那么可以使用“tail -n +m [文件名]”。

由于有的文件随时会有数据写入,如果想要该文件有数据写入时立刻显示到屏幕上,就要使用“-f”这个选项,它可以一直检测这个文件,新加入的数据就会被显示到屏幕上,直到你按下ctrl+c才会停止。

例题1:假如我想要显示 /etc/man_db.conf 的第11到第20行,该怎么办呢?

答:在第 11 到第 20 行,那么我取前20行,再取后10行,所以结果就是:『head -n 20 /etc/man_db.conf | tail -n 10』,这样就可以得到第11到第20行之间的内容了。

注意:这两个指令中间有个管道 (|) 的符号存在,这个管线的意思是:前面的指令所输出的信息,请通过管道交由后续的指令继续使用的意思。 所以,head -n 20 /etc/man_db.conf 会将文件内的前20行取出来,但不输出到屏幕上,而是转交给后续的tail指令继续处理。因此tail不需要接文件名。

 

例题2:承上一题,那如果我想要列出正确的行号呢?

答:还是利用管道,即写为“cat -n /etc/man_db.conf | head -n 20 | tail -n 10”

6.非纯文本文件:od(二进制)

[root@study ~]# od [-t TYPE] 文件名选项或参数:-t  :后面可以接各种『类型 (TYPE)』的输出,例如:      a       :利用默认的字符来输出;      c       :使用 ASCII 字符来输出      d[size] :利用十进制(decimal)来输出数据,每个整数占用 size bytes ;      f[size] :利用浮点数(floating)来输出数据,每个数占用 size bytes ;      o[size] :利用八进制(octal)来输出数据,每个整数占用 size bytes ;      x[size] :利用十六进制(hexadecimal)来输出数据,每个整数占用 size bytes ;

 

例题1:如果我想立即找到xidian这几个字的ASCII码,该怎样透过od来判断呢?

答:使用管道(|)。echo可以在屏幕上显示任何信息,而这个信息不由屏幕显示,而是交给od去继续处理,这样就可以得到对应的ASCII码了。如下图所示。

图3.1

7.修改文件时间或创建新文件:touch

首先来介绍一下文件时间。文件时间主要有三种,它们分别是:

(1)modification time(mtime):即修改时间。当文件的内容数据发生改变的时候,就会更新这个时间。

(2)status time(ctime):即文件的状态改变的时候,就会更新这个时间。例如修改文件的权限或者属性。

(3)access time(atime):即读取时间。当文件的内容被读取的时候,就会更新这个读取时间。

在默认的情况下,ls显示出来的是该文件的mtime,也就是这个文件的内容上次被更改的时间。我们可以看下图:

图3.2 时间测试

文件的时间是很重要的,因为,如果文件的时间误判的话,可能会造成某些程序无法顺利的运行。但是,如果发现了一个文件来自未来,该如何让该文件的时间变成现在的时间呢?答案是使用touch命令

[root@study ~]# touch [-acdmt] 文件名选项与参数:-a  :仅修订 access time;-c  :仅修改文件的时间,若该文件不存在则不建立新文件;-d  :后面可以接欲修改的日期而不用目前的日期,也可以使用 --date="日期或时间"-m  :仅修改文件修改时间(mtime)-t  :后面可以接欲修改的时间而不用目前的时间,格式为[YYYYMMDDhhmm]

注意:默认情况下,如果touch后面有接文件,则该文件的三个时间(atime/ctime/mtime)都会被修改为目前时间;若该文件不存在,则会主动新建一个空的文件

如图3.3所示。前4行为延时的创建一个空文件的过程。第5行~第10行演示了修改bashrc文件,将日期修改为两天前的方法和结果;第11~16行延时了将bashrc的日期修改为2018年12月2日11点19分。

我们发现,通过touch这个指令,我们可以轻易修改文件的日期和时间,并且可以新建一个空的文件。不过要注意的是,即使我们复制一个文件,并且复制所有的属性的时候,我们也无法复制ctime这个属性。

图3.3 修改时间延时

所以一定要记住,touch这个指令最常用的情况是:

(1)建立一个空文件;

(2)将某个文件的日期修改为目前(mtime和atime)。