l8.Linux文件及目录管理命令基础(二)

728 阅读26分钟

“ 本文正在参加「金石计划 . 瓜分6万现金大奖」 ”

5.2.6 ls:显示目录下内容及属性信息的命令

【命令星级】 ★★★★★

【功能说明】

ls命令可以理解为英文单词list的缩写,其功能是列出目录的内容及其内容属性信息(list directory contents)。该命令有点类似于DOS系统下的dir命令,有趣的是Linux下其实也有dir命令,但我们更习惯使用ls。

【语法格式】

ls [option] [file]
ls [选项] [<文件或目录>]

说明:

1)ls命令以及后面的选项和文件,每个元素之间都至少要有一个空格。

2)命令后面的选项和目录文件可以省略,表示查看当前路径的文件信息。

【选项说明】

表5-9针对ls命令的参数选项进行了说明。

表5-9 ls命令的参数选项及说明

b5-9.png

【应用范例】

在开始范例讲解之前,先做一些准备,顺便整合一下使用前面的命令。准备代码如下:

[root@centos7 ~]# mkdir test    #在根“/”下创建一个目录
[root@centos7 ~]# cd test/  #切换到test目录下。
[root@centos7 ~/test]# touch file{1..3}.txt
#批量创建若干文件。
[root@centos7 ~/test]# mkdir dir{1..3}
#批量创建多个目录。
[root@centos7 ~/test]# tree #显示前面创建的文件及目录结构。
.
├── dir1
├── dir2
├── dir3
├── file1.txt
├── file2.txt
└── file3.txt
​
3 directories, 3 files

范例5-21: 直接ls命令,不带任何参数。

[root@centos7 ~/test]# ls   #不加参数的结果,显示所有文件和目录
dir1  dir2  dir3  file1.txt  file2.txt  file3.txt

范例5-22: 使用-a参数显示所有文件,特别是隐藏文件。

[root@centos7 ~/test]# touch .file4.txt #创建一个隐藏文件,在Linux系统中以“.”(点号)开头的文件就是隐藏文件。
[root@centos7 ~/test]# ls
dir1  dir2  dir3  file1.txt  file2.txt  file3.txt
[root@centos7 ~/test]# ls -a
.  ..  dir1  dir2  dir3  file1.txt  file2.txt  file3.txt  .file4.txt
#说明:加了-a参数,就会把以“.”(点号)开头的内容显示出来。这里显示的第一个点号,表示当前目录,即test目录本身,而两个点号表示当前目录的上级目录。有关一个点、两个点的知识,在8.2.3节的ln命令中会有详细讲解。
[root@centos7 ~/test]# ls -A    #列出所有文件,包括隐藏文件,但不包括“.”和“..”这两个目录。
dir1  dir2  dir3  file1.txt  file2.txt  file3.txt  .file4.txt

范例5-23: 使用-l参数显示详细信息。

[root@centos7 ~/test]# ls -l    #此处时间属性列默认显示的是文件的最后一次修改时间。
total 0
drwxr-xr-x. 2 root root 6 Oct  6 16:42 dir1
drwxr-xr-x. 2 root root 6 Oct  6 16:42 dir2
drwxr-xr-x. 2 root root 6 Oct  6 16:42 dir3
-rw-r--r--. 1 root root 0 Oct  6 16:42 file1.txt
-rw-r--r--. 1 root root 0 Oct  6 16:42 file2.txt
-rw-r--r--. 1 root root 0 Oct  6 16:42 file3.txt
#说明:这个“-l”参数是最常用的参数,意思是用长格式列出目录下的文件类型、权限、连接数、属主(组)及创建修改时间的信息。这里的每个列的属性含义都需要熟练掌握,后文会详细讨论这些属性信息。

可能有人以及注意到了,创建或修改时间的格式没有年份的信息,那么如何显示时间的全部信息呢?见范例5-24。

范例5-24: 显示完整时间属性的参数--time-style=long-iso。

[root@centos7 ~/test]# ls -l --time-style=long-iso  #以long-iso方式显示时间,这个命令结果是非常棒的。
total 0
drwxr-xr-x. 2 root root 6 2020-10-06 16:42 dir1
drwxr-xr-x. 2 root root 6 2020-10-06 16:42 dir2
drwxr-xr-x. 2 root root 6 2020-10-06 16:42 dir3
-rw-r--r--. 1 root root 0 2020-10-06 16:42 file1.txt
-rw-r--r--. 1 root root 0 2020-10-06 16:42 file2.txt
-rw-r--r--. 1 root root 0 2020-10-06 16:42 file3.txt
#提示:这样的时间格式是不是看起来总是让人心情舒畅呢?--time-style的其他可选参数请大家自行测试。

对于上面的命令,说明如下。

1)--time-style包含的可选参数值有:full-iso、long-iso、iso、locate。默认值是locate。

2)在生产场景中经常会遇到同一目录下文件及目录时间的显示不一致的问题。所以需要用ls -l --time-style=long-iso来进行调整,如果觉得参数太多不好记,则可以设置一个别名来进行管理,详见后文的alias命令。

3)值得一提的是,执行ls -l等命令时,默认显示的是文件最后一次修改的时间(如果是新文件就是创建时间)。

4)ls --full-time用于显示完整的时间,等同于ls -l --time-style=full-iso。

既然ls -l输出结果的时间属性列为修改时间,那么能否改成其他的时间呢?例如,显示最后一次文件访问的时间。这当然是可以的,见下文。

范例5-25: 执行ls命令,带显示内容的访问时间属性的参数。

[root@centos7 ~/test]# stat file1.txt   #显示文件的属性及状态信息,stat命令后文会详细讲解,暂时不用理会。
  File: ‘file1.txt’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 803h/2051d  Inode: 16880703    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2020-10-06 16:42:01.535314886 +0800 #这里就是文件的访问时间,是我们现在需要关注的。
Modify: 2020-10-06 16:42:01.535314886 +0800
Change: 2020-10-06 16:42:01.535314886 +0800
 Birth: -
[root@oldboyedu2 ~/test]#date   #查看当前的系统时间。
Tue Oct  6 17:05:11 CST 2020

[root@centos7 ~/test]# cat file1.txt    #查看文件内容即表示访问文件了,cat命令后面会讲,暂时不用理会。
[root@centos7 ~/test]# stat file1.txt   #重新查看文件的访问时间。
  File: ‘file1.txt’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 803h/2051d  Inode: 16880703    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2020-10-06 17:04:28.927244778 +0800 #我们发现file1.txt的访问时间以及发生了变化。
Modify: 2020-10-06 16:42:01.535314886 +0800
Change: 2020-10-06 16:42:01.535314886 +0800
 Birth: -

[root@centos7 ~/test]# ls -l --time-style=long-iso --time=atime #增加--time=atime参数,显示访问时间。
total 0
drwxr-xr-x. 2 root root 6 2020-10-06 16:42 dir1
drwxr-xr-x. 2 root root 6 2020-10-06 16:42 dir2
drwxr-xr-x. 2 root root 6 2020-10-06 16:42 dir3
-rw-r--r--. 1 root root 0 2020-10-06 17:04 file1.txt
#文件的时间列确实发生了变化,是前面的访问时间无疑。
-rw-r--r--. 1 root root 0 2020-10-06 16:42 file2.txt
-rw-r--r--. 1 root root 0 2020-10-06 16:42 file3.txt

[root@centos7 ~/test]# ls -l --time-style=long-iso
total 0
drwxr-xr-x. 2 root root 6 2020-10-06 16:42 dir1
drwxr-xr-x. 2 root root 6 2020-10-06 16:42 dir2
drwxr-xr-x. 2 root root 6 2020-10-06 16:42 dir3
-rw-r--r--. 1 root root 0 2020-10-06 16:42 file1.txt
#这里是文件的默认修改时间列。
-rw-r--r--. 1 root root 0 2020-10-06 16:42 file2.txt
-rw-r--r--. 1 root root 0 2020-10-06 16:42 file3.txt
#通过以上实践,我们可以得出理论了。--time=atime显示的确实是访问时间,而非默认的修改时间。

对于上面的命令,说明如下。

1)与之相关的命令还有ls -l --time-style=long-iso --time=ctime,用于显示文件的改变时间。

2)有关文件时间列及mtime、atime、ctime的知识在介绍touch命令时已经讲解过了。

范例5-26: 执行ls命令,带-F参数(有些类似于tree命令的-F)

[root@centos7 ~/test]# ls -F
dir1/  dir2/  dir3/  file1.txt  file2.txt  file3.txt
#说明:加了-F之后,我们可以清晰地看到所有目录的结尾都加上了斜线/。这样的功能对于工作有什么用呢?当然有用了,例如,我们要过滤出所有的目录来,那么只需要将带斜线的过滤出来就可以了。
[root@centos7 ~/test]# ls -F|grep / #过滤目录,grep命令的具体用法见后面grep章节。
dir1/
dir2/
dir3/
[root@centos7 ~/test]# ls -F|grep -v /  #过滤普通文件。
file1.txt
file2.txt
file3.txt
#说明:ls的-F参数是在文件结尾加上文件类型指示符号(*、/、=、@、|,其中的一个)。

范例5-27: 使用-d参数只显示目录本身的信息。

有时候我们想查看目录本身的信息,但是若使用“ls 目录”命令,就会显示目录里面的内容。示例代码如下:

[root@centos7 ~/test]# ls -l dir1   #这样根本无法查看目录本身的信息,除非到上级目录中查看。
total 0

如果只是想显示目录本身的信息,那么这个时候参数-d就能派上用场了,示例代码如下:

[root@centos7 ~/test]# ls -ld dir1  #加-d参数就可以如愿以偿了。
drwxr-xr-x. 2 root root 6 Oct  6 16:42 dir1

范例5-28: 使用-R参数递归查看目录。

[root@centos7 ~/test]# mkdir -p dir1/sub1/test  #递归创建目录的命令。
[root@centos7 ~/test]# ls -R dir1   #类似于tree但没有tree好用的方法。
dir1:
sub1
​
dir1/sub1:
test
​
dir1/sub1/test:

范例5-29: ls命令别名的相关知识及设置ls别名。

可通过如下命令查看ls在系统中的默认别名设置,执行等号前面的内容就会调用后面的命令:

[root@centos7 ~/test]# alias |grep ls   #alias命令的用法请参见相应的alias章节。
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
#提示:什么是别名呢?别名很好理解,就是另外一个名字而已。

例如,显示时间格式的参数太长,这里就可以做个别名,示例代码如下:

[root@centos7 ~/test]# alias lst='ls -l --time-style=long-iso'  #配置命令别名
[root@centos7 ~/test]# alias|grep lst   #检查命令别名是否生效。
alias lst='ls -l --time-style=long-iso'
[root@centos7 ~/test]# lst
#执行命令别名,检查效果。
total 0
drwxr-xr-x. 3 root root 18 2020-10-06 17:26 dir1
drwxr-xr-x. 2 root root  6 2020-10-06 16:42 dir2
drwxr-xr-x. 2 root root  6 2020-10-06 16:42 dir3
-rw-r--r--. 1 root root  0 2020-10-06 16:42 file1.txt
-rw-r--r--. 1 root root  0 2020-10-06 16:42 file2.txt
-rw-r--r--. 1 root root  0 2020-10-06 16:42 file3.txt
#注意:这里的别名是临时生效的,如果希望永久生效则需要将别名放到环境变量的配置里才可以。

范例5-30: 查找最近更新过的文件。

在工作中,我们经常需要查看一个包含很多文件的目录,找出最近更新过但不知道具体文件名的文件,这时可以用ls -lrt或者ls -rt这个组合命令,示例代码如下:

[root@centos7 ~/test]# touch /opt/test.txt  #创建一个新文件,假设不知道名字,呢如何快速找到它?
[root@centos7 ~/test]# ls -lrt /opt/    #-t是按时间排序,-r是倒序,即按时间倒序排序。
total 0
-rw-r--r--. 1 root root 0 Oct  6 15:14 a.txt
-rw-r--r--. 1 root root 0 Oct  6 17:35 test.txt
#不用翻屏回查,最后一屏的最后一行就是我们需要查找的文件。如果直接定位文件还可以用如下命令。
[root@centos7 ~/test]# ls -lrt /opt/|tail -1    #tail命令后面会讲。
-rw-r--r--. 1 root root 0 Oct  6 17:35 test.txt

【ls命令输出内容的属性解读】

使用ls命令之后,通常会有类似如下的输出内容:

[root@centos7 ~/test]# ls -lhi  #l参数前面以及详细讲解过了,-h参数的作用是将文件的大小以人类可读的方式显示,像下面的4.0K你就能很容易知道文件的大小,-i参数的作用是显示文件的Inode值。
total 0
33914847 drwxr-xr-x. 3 root root 18 Oct  6 17:26 dir1
50333656 drwxr-xr-x. 2 root root  6 Oct  6 16:42 dir2
  142528 drwxr-xr-x. 2 root root  6 Oct  6 16:42 dir3
16880703 -rw-r--r--. 1 root root  0 Oct  6 16:42 file1.txt
16880737 -rw-r--r--. 1 root root  0 Oct  6 16:42 file2.txt
16880749 -rw-r--r--. 1 root root  0 Oct  6 16:42 file3.txt

上述命令结果中各列的含义如下。

第一列:Inode索引节点编号。

第二列:文件类型及权限(第一个字符为类型,后9个字符为文件权限符号)。

第三列:硬链接个数(详情请参看ln命令(8.2.3节)的讲解)。

第四列:文件或目录所属的用户(属主)。

第五列:文件或目录所属的组。

第六列:文件或目录的大小。

第七、八、九列:文件或目录的修改时间。

第十列:实际的文件名或目录。

详细解释见图5-3。

【ls输出的文件属性举例说明】

下面以oldboy文件为例说明输出文件的属性细节(具体见表5-10),具体列的内容请参考图5-3。

t5-3.png

图5-3 ls命令输出内容的属性解读

表5-10 ls输出的文件属性细节说明

b5-10.png

5.2.7 cp:复制文件或目录

【命令星级】 ★★★★★

【功能说明】

cp命令可以理解为英文单词copy的缩写,其功能为复制文件或目录。

【语法格式】

cp [option] [source] [dest]
cp [选项] [源文件] [目标文件]

说明: cp命令以及后面的选项和文件,每个元素之间都至少要有一个空格。

【选项说明】

表5-11针对cp命令的参数选项进行了说明。

表5-11 cp命令的参数选项及说明

b5-11.png

【应用范例】

范例5-31: 无参数和带参数-a的比较。

[root@centos7 ~/test]#  pwd
/root/test
[root@centos7 ~/test]# ll -h    #查看当前文件的时间属性,读者以自己的系统时间为准。
total 0
drwxr-xr-x. 3 root root 18 Oct  6 17:26 dir1
drwxr-xr-x. 2 root root  6 Oct  6 16:42 dir2
drwxr-xr-x. 2 root root  6 Oct  6 16:42 dir3
-rw-r--r--. 1 root root  0 Oct  6 16:42 file1.txt
-rw-r--r--. 1 root root  0 Oct  6 16:42 file2.txt
-rw-r--r--. 1 root root  0 Oct  6 16:42 file3.txt
[root@centos7 ~/test]# cp file1.txt file4.txt   #复制file1.txt为file4.txt
[root@centos7 ~/test]# cp -a file1.txt file5.txt    #使用-a参数复制file1.txt为file5.txt。
[root@centos7 ~/test]# ll -h    #再次查看当前文件的时间属性。
total 0
drwxr-xr-x. 3 root root 18 Oct  6 17:26 dir1
drwxr-xr-x. 2 root root  6 Oct  6 16:42 dir2
drwxr-xr-x. 2 root root  6 Oct  6 16:42 dir3
-rw-r--r--. 1 root root  0 Oct  6 16:42 file1.txt
#此行是源文件。
-rw-r--r--. 1 root root  0 Oct  6 16:42 file2.txt
-rw-r--r--. 1 root root  0 Oct  6 16:42 file3.txt
-rw-r--r--. 1 root root  0 Oct  6 17:57 file4.txt
#此行是未使用任何参数。
-rw-r--r--. 1 root root  0 Oct  6 16:42 file5.txt
#此行是使用-a参数进行复制,属性不变。

可以发现,使用-a参数进行复制时,文件的时间属性没有改变,-a参数的功能包含-p参数保持文件的属性功能。

范例5-32: 使用-i参数的例子

[root@centos7 ~/test]# cp -i file1.txt file5.txt    #使用-i参数复制文件,会提示是否覆盖文件。
cp: overwrite ‘file5.txt’? ^C
[root@centos7 ~/test]# cp file1.txt file5.txt   #不适用-i参数结果是一样的,为什么呢?
cp: overwrite ‘file5.txt’? ^C
[root@centos7 ~/test]# alias cp #原因是系统为cp命令默认设置了别名。
alias cp='cp -i'

CentOS系统默认为cp命令设置了别名,即增加了-i的参数。但是在Shell脚本中执行cp命令时,没有-i参数时并不会询问是否覆盖。这是因为命令行和Shell脚本执行时的环境变量不同。不过在脚本中一般使用命令的全路径。

范例5-33: 使用-r参数复制目录。

[root@centos7 ~/test]# cp dir1 dir2/    #复制dir1到dir2,但结果显示跳过目录dir1。
cp: omitting directory ‘dir1’
[root@centos7 ~/test]# cp -r dir1 dir2/ #若使用-r参数则复制成功。
[root@centos7 ~/test]# tree dir2    #查看复制结果。
dir2
└── dir1
    └── sub1
        └── test
​
3 directories, 0 files
#提示:使用-a参数也可以达到相同的效果,因为-a参数相当于“dpr”三个参数。

范例5-34: cp覆盖文件不提示是否覆盖的几种方法.。

解题思路: 屏蔽系统默认的对应的命令别名。

第一种方法,使用命令全路径,示例代码如下:

[root@centos7 ~/test]# cp file1.txt file2.txt
cp: overwrite ‘file2.txt’? y    #提示要输入y以确认覆盖,输入n则为不覆盖。
[root@centos7 ~/test]# which cp #查看cp的系统别名。
alias cp='cp -i'
    /usr/bin/cp #CentOS 7系统里是/usr/bin/co,为了兼容CentOS 6,将/bin指向了/usr/bin/cp。
[root@oldboyedu2 ~/test]#/bin/cp file1.txt file2.txt
#使用cp命令的绝对路径,即可屏蔽别名。

第二中方法,命令开头使用反斜线\,示例代码如下:

[root@centos7 ~/test]# \cp file1.txt file2.txt
#使用“\”屏蔽系统别名。

第三种方法,取消cp的别名,但重启系统或退出Xshell失效,示例代码如下:

[root@centos7 ~/test]# unalias cp   #alias设置别名,unalias取消别名,具体用法见对应章节的内容详解。
[root@centos7 ~/test]# cp file1.txt file2.txt

第四种为杀鸡取卵的方法,用于开拓思路,不建议采用,示例代码如下:

[root@centos7 ~/test]# cat ~/.bashrc
# .bashrc# User specific aliases and functionsalias rm='rm -i'
alias cp='cp -i'    #编辑这个文件,注释掉本行,重启后生效。“.bashrc”这个文件在开机时会加载。
alias mv='mv -i'# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

范例5-35: 快速备份文件案例。

通常我们备份文件时会使用下面的格式:

[root@centos7 ~/test]# cp /etc/ssh/sshd_config  /etc/ssh/sshd_config.ori
#观察上面的格式,我们可以发现有一部分路径重复了。因此有了下面的快捷写法,使用“{}”的用法,两种方法是等效的。
[root@centos7 ~/test]# cp /etc/ssh/sshd_config{,.ori}
#这种方法的原理是bash对大括号的展开操作,/etc/ssh/sshd_config{,.ori}展开成/etc/ssh/sshd_config  /etc/ssh/sshd_config.ori再传给cp命令。

5.2.8 mv:移动或重命名文件、目录

【命令星级】 ★★★★★

【功能说明】

mv命令可以理解为英文单词move的缩写,其功能是移动或重命名文件(move/rename files)。

【语法格式】

mv [option] [source] [dest]
mv [选项] [源文件] [目标文件]

说明: mv命令以及后面的选项和文件,每个元素之间都至少要有一个空格。

【选项说明】

表5-12针对mv命令的参数选项进行了说明。

表5-12 mv命令的参数选项及说明

b5-12.png

【应用范例】

范例5-36: 对文件改名的例子。

[root@centos7 ~/test]# ls
dir1  dir2  dir3  file1.txt  file2.txt  file3.txt  file4.txt  file5.txt
[root@centos7 ~/test]# mv file5.txt file6.txt   #若file6.txt不存在,则将file5.txt重命名为file6.txt.
[root@centos7 ~/test]# ls
dir1  dir2  dir3  file1.txt  file2.txt  file3.txt  file4.txt  file6.txt
[root@centos7 ~/test]# mv file4.txt file6.txt #若file6.txt存在,则将file4.txt覆盖file6.txt
mv: overwrite ‘file6.txt’? y    #由于系统默认为mv设置了别名,因此会提示是否覆盖。
[root@centos7 ~/test]# alias mv
alias mv='mv -i'    #-i参数的功能是若目标文件存在,则会询问是否覆盖。
[root@centos7 ~/test]# ls
dir1  dir2  dir3  file1.txt  file2.txt  file3.txt  file6.txt
[root@centos7 ~/test]# \mv  file3.txt file6.txt #若使用“\”屏蔽系统别名,则不会询问是否覆盖了。
[root@oldboyedu2 ~/test]#ls
dir1  dir2  dir3  file1.txt  file2.txt  file6.txt

范例5-37: 移动文件的例子。

移动单个文件的示例代码如下:

[root@centos7 ~/test]# ls dir1
sub1
[root@centos7 ~/test]# mv file6.txt dir1/   #dir1为目录且该目录已存在,则移动file6.txt到dir1下,若dir1不存在,则重命名为dir1的普通文件。
[root@centos7 ~/test]# ls
dir1  dir2  dir3  file1.txt  file2.txt
[root@centos7 ~/test]# ls dir1
file6.txt  sub1
​
#移动多个文件:
[root@centos7 ~/test]# mv file1.txt file2.txt dir1/ #第一种方式:多个文件在前,目录在后。
[root@centos7 ~/test]# ls
dir1  dir2  dir3  
[root@centos7 ~/test]# ls dir1
file1.txt  file2.txt  file6.txt  sub1
[root@centos7 ~/test]# mv dir1/file* .  #还原实验环境,“file*”匹配所有以file开头的文件。
[root@centos7 ~/test]# ls
dir1  dir2  dir3  file1.txt  file2.txt  file6.txt
[root@centos7 ~/test]# ls dir1
sub1

范例5-38: 将源和目标调换移动文件到目录(-t参数)。

[root@centos7 ~/test]# ls
dir1  dir2  dir3  file1.txt  file2.txt  file6.txt
[root@centos7 ~/test]# mv -t dir1/ file1.txt file2.txt file6.txt    #使用-t参数将源和目标进行调换,-t后接目录,最后是要移动的文件。
[root@centos7 ~/test]# ls
dir1  dir2  dir3
[root@centos7 ~/test]# ls dir1/
file1.txt  file2.txt  file6.txt  sub1

范例5-39: 移动目录的例子。

[root@centos7 ~/test]# ls 
dir1  dir2  dir3
[root@centos7 ~/test]# mv dir1 dir5 #目录dir5不存在,将目录dir1改名为dir5
[root@centos7 ~/test]# ls
dir2  dir3  dir5
[root@centos7 ~/test]# ls dir5/
file1.txt  file2.txt  file6.txt  sub1
[root@centos7 ~/test]# mv dir2 dir5 #若存在目录dir5,则将dir2移动到dir5中
[root@centos7 ~/test]# ls dir5/
dir2  file1.txt  file2.txt  file6.txt  sub1
[root@centos7 ~/test]# mv dir3/ dir5/   #若在源目录结尾加“/”则不影响结果,但是为了规范和简单起见,建议不加“/”。
[root@centos7 ~/test]# ls
dir5
[root@centos7 ~/test]# ls dir5/
dir2  dir3  file1.txt  file2.txt  file6.txt  sub1

5.2.9 rm:删除文件和目录

【命令星级】 ★★★★★

【功能说明】

rm命令可以理解为英文单词remove的缩写,其功能是删除一个或多个文件或目录(remove files or directories)。这是Linux系统里最危险的命令之一,请慎重使用。

【语法格式】

rm [option] [file]
rm [选项] [<文件或目录>]

说明: rm命令以及后面的选项和文件目录,每个元素之间都至少要有一个空格。

【选项说明】

表5-13针对rm命令的参数选项进行了说明。

表5-13 rm命令的参数选项及说明

b5-13.png

【应用范例】

示例准备代码如下:

[root@centos7 ~]# mkdir -p /data/dir{1..3}  #使用绝对路径创建目录。
[root@centos7 ~]# touch /data/file{1..3}.txt
[root@centos7 ~]# tree /data/
data/
├── dir1
├── dir2
├── dir3
├── file1.txt
├── file2.txt
└── file3.txt
​
3 directories, 3 files
[root@centos7 ~]# cd /data
[root@centos7 /data]# ls
dir1  dir2  dir3  file1.txt  file2.txt  file3.txt

范例5-40: 不带参数删除的实践示例。

[root@centos7 /data]# rm file3.txt 
rm: remove regular empty file ‘file3.txt’? n
#若输入y就会删除文件,若不想删除则输入n。
[root@centos7 /data]# alias rm
alias rm='rm -i'    #上面会出现提示的原因是rm被设置了系统别名,默认使用了-i参数。
#屏蔽别名的方法已经在5.2.7节的cp命令讲解中介绍过了,这里不再讲述。

范例5-41: 强制删除的实践示例。

[root@centos7 /data]# rm -f file3.txt #-f参数强制删除,不提示。
[root@centos7 /data]# ls
dir1  dir2  dir3  file1.txt  file2.txt

提示: 使用-f参数强制删除会直接覆盖系统定义的别名。

范例5-42: 递归删除的实践示例。

[root@centos7 /data]# mkdir -p dir1/a/b
[root@centos7 /data]# tree dir1
dir1
└── a
    └── b
​
2 directories, 0 files
[root@centos7 /data]# rm dir1   #若无参数就会无法删除目录。
rm: cannot remove ‘dir1’: Is a directory
[root@centos7 /data]# rm -r dir1    #使用-r可以递归删除,但有确认提示,可以使用-f进行强制删除。
rm: descend into directory ‘dir1’? y
rm: descend into directory ‘dir1/a’? y
rm: remove directory ‘dir1/a/b’? n
rm: remove directory ‘dir1/a’? n
rm: remove directory ‘dir1’? n
#备注:若加上-f参数就不需要一一确认了,例如rm -rf dir1。若删除的对象不是目录(文件)就不要再使用-r参数了,这样做会很危险,也没有必要。

【有关删除的实践经验分享】

常在河边走,哪有不湿鞋!但如果能遵守下面的要领就可以少湿鞋甚至不湿鞋!

1)用mv替代rm,不要着急删除,而是先移动到回收站“/tmp”。

2)删除前请务必做好备份,最好是异机备份,出现问题随时可还原。

3)如果非要删除,则请用find替代rm,包括通过系统定时任务等清理文件方法。

下面是在生产环境中删除文件或目录的教安全的方法,命令如下:

find . -type f -name "*.txt" -mtime +7|xargs rm -f  #与xargs搭配使用,具体用法见find命令的详细讲解。
find . -type f -mtime +7 -exec rm {} ;     #使用find的exec。

4)如果非要通过rm命令删除,则请先切换目录再删,能不适用通配符的就尽量不用通配符。对文件的删除禁止使用"rm -rf 文件名"方法,因为“rm -rf”误删除目录时并不会有提示,该操作非常危险。最多使用"rm -f 文件名"方法,推荐使用“rm 文件名”方法。

[root@centos7 /data]# mkdir /oldboy
[root@centos7 /data]# touch /oldboy/test{1..2}
[root@centos7 /data]# cd oldboy/
[root@centos7 /data/oldboy]# rm -f test{1..2}
[root@centos7 /data/oldboy]# ls

5)如果非要使用通配符,则请按下面的方法进行:

[root@centos7 /data]# cd /oldboy/
[root@centos7 /data/oldboy]# touch a b
[root@centos7 /data/oldboy]# ls
a  b
[root@centos7 /data/oldboy]# rm -f ./*  #加上“./”。禁止使用rm -rf /oldboy/*,这个命令如果多了空格可能会带来灾难。
[root@centos7 /data/oldboy]# ls
[root@centos7 /oldboy]# touch a b 
[root@centos7 /oldboy]# ls
a  b
[root@centos7 /oldboy]# rm -rf /oldboy/*
#“*”的前面如果不小心多了空格,则会删除当前目录的所有内容,例如下面的命令。
[root@centos7 /oldboy]# rm -rf /oldboy/ *   #会把当前目录(根)下的目录、文件全部删除。

6)额外再补充一点,要慎用“rsync-delete”。

多数情况下,删除后是可以恢复的(例如,可通过恢复工具ext3grep来实现),但一定会影响业务,例如,造成停机,或者数据丢失了较长时间,用户访问不了等。未雨绸缪永远比发生了再解决好得多。

更过内容可参考老男孩博客:oldboy.blog.51cto.com/2561410/168…

5.3 Linux文件及目录命令核心知识的试题及详解

本节将要讲解的试题是对读者阅读本章内容后的一个大考察,建议先不要看答案,看能否在Linux命令行下自行解答,然后再与参考答案进行对比,并深入了解题中遇到的相关Linux核心知识和操作规范。

5.3.1 有关cd/pwd/mkdir/ls命令试题

【考题】 切换到“/tmp”目录下,查看当前的工作位置,同时创建data1、data2、data3共3个目录。

【参考答案】

[root@centos7 ~]# cd /tmp/  #切换到/tmp目录
[root@centos7 /tmp]# pwd    #查看当前的工作位置。
/tmp
[root@centos7 /tmp]# mkdir data1 data2 data3    #创建data1、data2、data3共3个目录
[root@centos7 /tmp]# ls #操作后查看创建结果,这是个号的习惯。
data1                         
data2                         
data3
[root@centos7 /tmp]# tree -d
.
├── data1
├── data2
├── data3

【重点解析】

创建目录可以一次性到位,且创建多级目录一般要加-p参数,以防止出错,示例代码如下:

[root@centos7 /tmp]# cd -   #切换到当前用户家目录下。
/oldboy
[root@centos7 /oldboy]# rm -rf /tmp/*   #删除/tmp/所有内容,“*”代表所有,此命令很危险。
[root@centos7 /oldboy]# mkdir -p  /tmp/data{1,2,3}  #利用大括号批量创建,加-p递归创建,{1,2,3}等同于{1..3}。
[root@centos7 /oldboy]# ls /tmp #接路径直接查看指定目录下的内容。
data1  data2  data3

5.3.2 有关touch/tree/file命令试题

【考题】 接5.3.1的考题,分别在data1、data2、data3目录下创建3个文件,名字分别为oldboy1、oldboy2、oldboy3,然后查看/tmp目录的整个目录结构情况,最后检查下data1和oldboy1两个对象的属性。

【参考答案】

解答这道考题通常最容易想到的可能是分别在每个目录下处理的笨办法,其实还可以采用另一种快速的方法,注意,此考题依赖5.3.1节考题的结果,解题代码如下:

[root@centos7 ~]# touch /tmp/data{1..3}/oldboy{1..3}    #一步到位的答案。
[root@centos7 /oldboy]# tree
-bash: /usr/bin/tree: No such file or directory
#提示没有文件或目录。
[root@centos7 /oldboy]# rpm -qa tree
#查看tree命令是否安装,没有安装。
[root@centos7 /oldboy]# yum install -y tree
#安装tree命令,需要系统能够上网才行。
[root@centos7 ~]# tree /tmp
/tmp
├── data1
│   ├── oldboy1
│   ├── oldboy2
│   └── oldboy3
├── data2
│   ├── oldboy1
│   ├── oldboy2
│   └── oldboy3
└── data3
    ├── oldboy1
    ├── oldboy2
    └── oldboy3
​
3 directories, 9 files
[root@centos7 ~]# ls -ld /tmp/data1 #加-ld参数,是查看data1目录本身属性
drwxr-xr-x. 2 root root 51 Oct  6 20:15 /tmp/data1
#"d"开头表示data1是目录。
[root@centos7 ~]# ls -ld /tmp/data{1..3}/oldboy1    #查看data1、data2、data3下的oldboy1文件的属性
-rw-r--r--. 1 root root 0 Oct  6 20:15 /tmp/data1/oldboy1   #"-"开头表示oldboy1是文件。
-rw-r--r--. 1 root root 0 Oct  6 20:15 /tmp/data2/oldboy1
-rw-r--r--. 1 root root 0 Oct  6 20:15 /tmp/data3/oldboy1

【重点解析】

  • 大括号{}的使用。
  • ls -l命令的使用,以及通过属性开头的符号区分目录和文件只是,“-”表示文件,“d”表示目录。

5.3.3 有关cp命令的试题

【考题】 将/etc/hosts文件复制到/tmp/data1下,然后将data1目录复制到/opt下。

【参考答案】

[root@centos7 ~]# cp /etc/hosts /tmp/data1  #将/etc/hosts文件复制到/tmp/data1下。
[root@centos7 ~]# ls /tmp/data1
hosts  oldboy1  oldboy2  oldboy3    #复制结果。
[root@centos7 ~]# cp -a /tmp/data1 /opt #将data1目录复制到/opt下,注意-r。
[root@centos7 ~]# tree /opt/data1
/opt/data1  #复制结果。
├── hosts
├── oldboy1
├── oldboy2
└── oldboy3

【重点解析】

cp功能表示复制文件或目录,但默认不加参数则不能复制目录。如果要复制目录则必须使用-r或者-a参数,以下参数在前文讲解命名时已经讲解过,请读者重点掌握。

-a 相当于-pdr,复制目录页可以使用-a参数。
-r 递归,复制目录,目录及其子孙后代。
-p 复制文件同时保持文件属性不变。

5.3.4 有关mv/rm命令的试题

【考题】 将/tmp/data1目录移动到/root目录下,然后删除/opt/data1目录下的host文件,最后删除/opt下的data1目录。

【参考答案】

[root@centos7 ~]# cd /tmp   #mv是一个很危险的命令,操作时最好进入到对象的上一层次操作。
[root@centos7 /tmp]# mv data1 /root #将/tmp/data1目录移动到/root目录下。
[root@centos7 /tmp]# ls 
anaconda-ks.cfg  b.txt  data1  test2
[root@centos7 /tmp]# ls data1/
hosts  oldboy1  oldboy2  oldboy3
[root@centos7 /tmp]# cd /opt/data1  #rm是一个很危险的命令,操作前最好进入到对象的上一层操作。
[root@centos7 /opt/data1]# rm hosts     #删除前请确认。
rm: remove regular file 'hosts'?yes #输入yes删除。
[root@centos7 /opt/data1]# ls 
oldboy1  oldboy2  oldboy3   #hosts已删。
[root@centos7 /opt/data1]# rm -f oldboy1    #可以加-f直接强制删除,不提示。
[root@centos7 /opt/data1]# ls 
oldboy2  oldboy3    ##oldboy1已删。
[root@centos7 /opt/data1]# cd ..    #切换到上一级目录,这是在cd命令章节已讲解过。
[root@centos7 /opt]# pwd    #确认当前所在的位置,防止误删。
/opt
[root@centos7 /opt]# ls #确认对象是否存在。
data1 rh
[root@centos7 /opt]# rm -rf data1   #强制删除目录和目录下的所有文件,不提示(危险命令)。
[root@centos7 /opt]# ls 
 rh

【重点解析】

  • 操作rm、mv命令前,最好对操作的对象先做好备份。
  • 操作rm、mv命令最好切换到指定的目录,且最好不要再根下直接操作。
  • 这里的data1与/data1/是 没有区别的,都表示目录及目录下的所有内容,其他软件场景可能会有区别。
  • 删除目录一般使用-rf参数,删除前务必备份,以防误删。
  • 企业里替代rm以及使用mv的注意事项请参见5.2.9节。