learn-tech/专栏/重学操作系统-完/06目录结构和文件管理指令:rm-rf指令的作用是?.md
2024-10-16 11:00:45 +08:00

14 KiB
Raw Blame History

                        因收到Google相关通知网站将会择期关闭。相关通知内容
                        
                        
                        06  目录结构和文件管理指令rm  -rf 指令的作用是?
                        通过模块一的学习,你应该掌握了计算机组成原理的重点知识,到了模块二,我们开始学习 Linux 指令,它是操作系统的前端,学好这部分内容一方面可以帮助你应对工作场景,另一方面可以让你在学习操作系统底层知识前,对 Linux 有一个大概的了解。

接下来我们依然通过一道常见的高频面试题引出今天的主要内容。面试题如下请你说说rm / -rf的作用

相信 90% 的同学是知道这个指令的。这里先预警一下,你千万不要轻易在服务器上尝试。要想知道这条指令是做什么的,能够帮助我们解决哪些问题,那就请你认真学习今天的内容。在本课时的最后我会公布这道题目的分析过程和答案。

什么是 Shell

在我们学习 Linux 指令之前,先来说一下什么是 ShellShell 把我们输入的指令,传递给操作系统去执行,所以 Shell 是一个命令行的用户界面。

早期程序员没有图形界面用,就用 Shell。而且图形界面制作成本较高不能实现所有功能因此今天的程序员依然在用 Shell。

你平时还经常会看到一个词叫作bashBourne Again Shell它是用 Shell 组成的程序。这里的 Bourne 是一个人名Steve Bourne 是 bash 的发明者。

我们今天学习的所有指令不是写死在操作系统中的而是一个个程序。比如rm指令你可以用which指令查看它所在的目录。如下图所示你会发现rm指令在/usr/bin/rm目录中。

如上图所示ramroll是我的英文名字ubuntu 是我这台机器的名字。我输入了which rm然后获得了/usr/bin/rm的结果最终执行这条指令的是操作系统连接我和操作系统的程序就是 Shell。

Linux 对文件目录操作的指令就工作在 Shell 上,接下来我们讲讲文件目录操作指令。

Linux 对文件目录的抽象

Linux 对文件进行了一个树状的抽象。/代表根目录,每一节目录也用/分开,所以在上图所展示的/usr/bin/rm中第一级目录是/根目录第二级目录是usr目录第三级是bin目录。最后的rm是一个文件。

路径path

像/usr/bin/rm称为可执行文件rm的路径。路径就是一个文件在文件系统中的地址。如果文件系统是树形结构那么通常一个文件只有一个地址路径

目标文件的绝对路径Absolute path也叫作完全路径full path是从/开始,接下来每一层都是一级子目录,直到定位到目标文件为止。

如上图所示的例子中,/usr/bin/rm就是一个绝对路径。

工作目录

为了方便你工作Shell 还抽象出了工作目录。当用户打开 Shell 的时候Shell 就会给用户安排一个工作目录。因此也就产生了相对路径。

相对路径Relative path是以工作目录为基点的路径。比如

当用户在/usr目录下的时候rm文件的相对路径就是bin/rm 如果用户在/usr/bin目录下的时候rm文件的路径就是./rm或者rm这里用.代表当前目录; 如果用户在/usr/bin/somedir下那么rm的相对路径就是../rm这里用..代表上一级目录。

我们使用cdchange directory指令切换工作目录既可以用绝对路径也可以用相对路径。 这里我要强调几个注意事项:

输入cd不带任何参数会切换到用户的家目录Linux 中通常是/home/{用户名}。以我自己为例,我的家目录是/home/ramroll 输入cd .什么都不会发生,因为.代表当前目录; 输入cd..会回退一级目录,因为..代表上级目录。

利用上面这 3 种能力,你就可以方便的构造相对路径了。

Linux提供了一个指令pwdPrint Working Directory查看工作目录。下图是我输入pwd的结果。

你可以看到我正在/home/ramroll/Documents目录下工作。

几种常见的文件类型

另一方面Linux 下的目录也是一种文件;但是文件也不只有目录和可执行文件两种。常见的文件类型有以下 7 种:

普通文件(比如一个文本文件); 目录文件(目录也是一个特殊的文件,它用来存储文件清单,比如/也是一个文件); 可执行文件上面的rm就是一个可执行文件 管道文件(我们会在 07 课时讨论管道文件); Socket 文件(我们会在模块七网络部分讨论 Socket 文件); 软链接文件(相当于指向另一个文件所在路径的符号); 硬链接文件(相当于指向另一个文件的指针,关于软硬链接我们将在模块六文件系统部分讨论)。

你如果使用ls -F就可以看到当前目录下的文件和它的类型。比如下面这种图

  • 结尾的是可执行文件; = 结尾的是 Socket 文件; @ 结尾的是软链接; | 结尾的管道文件; 没有符号结尾的是普通文件; / 结尾的是目录。

设备文件

Socket 是网络插座是客户端和服务器之间同步数据的接口。其实Linux 不只把 Socket 抽象成了文件,设备基本也都被抽象成了文件。因为设备需要不断和操作系统交换数据。而交换方式只有两种——读和写。所以设备是可以抽象成文件的,因为文件也支持这两种操作。

Linux 把所有的设备都抽象成了文件比如说打印机、USB、显卡等。这让整体的系统设计变得高度统一。

至此,我们了解了 Linux 对文件目录的抽象,接下来我们看看具体的增删改查指令。

文件的增删改查

增加

创建一个普通文件的方法有很多最常见的有touch指令。比如下面我们创建了一个 a.txt 文件。

touch指令本来是用来更改文件的时间戳的但是如果文件不存在touch也会帮助创建一个空文件。

如果你拿到一个指令不知道该怎么用比如touch你可以用man touch去获得帮助。man意思是 manual就是说明书的意思这里指的是系统的手册。如果你不知道man是什么也可以使用man man。下图是使用man man的结果

另外如果我们需要增加一个目录就需要用到mkdir指令 make directory比如我们创建一个hello目录如下图所示

查看

创建之后我们可以用ls指令看到这个文件ls是 list 的缩写。下面是指令 ls 的执行结果。

我们看到在当前的目录下有一个a.txt文件还有一个hello目录。如果你知道当前的工作目录就可以使用pwd指令。

如果想看到a.txt更完善的信息还可以使用ls -l。-l是ls指令的可选参数。下图是ls -l的结果你可以看到a.txt更详细的描述。

如上图所示我们看到两个ramroll它们是a.txt所属的用户和所属的用户分组刚好重名了。Sep 13是日期。 中间有一个0是a.txt的文件大小目前a.txt中还没有写入内容因此大小是0。

另外虽然hello是空的目录但是目录文件 Linux 上来就分配了4096字节的空间。这是因为目录内需要保存很多文件的描述信息。

删除

如果我们想要删除a.txt可以用rm a.txt如我们要删除hello目录可以用rm hello。rm是 remove 的缩写。

但是当我们输入rm hello的时候会提示hello是一个目录不可以删除。因此我们需要增加一个可选项比如-r即 recursive递归。目录是一个递归结构所以需要用递归删除。最后你会发现rm hello -r删除了hello目录。

接下来我们尝试在 hello 目录下新增一个文件比如相对路径是hello/world/os.txt。需要先创建 hello/world 目录。这种情况会用到mkdir的-p参数这个参数控制mkdir当发现目标目录的父级目录不存在的时候会递归的创建。以下是我们的执行结果

修改

如果需要修改一个文件可以使用nano或者vi编辑器。类似的工具还有很多但是nano和vi一般是linux自带的。

这里我不展开讲解了,你可以自己去尝试。在尝试的过程中如果遇到什么问题,可以写在留言区,我会逐一为你解答。

查阅文件内容

在了解了文件的增删改查操作后下面我们来学习查阅文件内容。我们知道Linux 下查阅文件内容,可以根据不同场景选择不同的指令。

当文件较小时比如一个配置文件想要快速浏览这个文件可以用cat指令。下面 cat 指令帮助我们快速查看/etc/hosts文件。cat指令将文件连接到标准输出流并打印到屏幕上。

标准输出流Standard Output也是一种文件进程可以将要输出的内容写入标准输出流文件这样就可以在屏幕中打印。

如果用cat查看大文件比如一个线上的日志文件因为动辄有几个 G控制台打印出所有的内容就要非常久而且刷屏显示看不到东西。

而且如果在线上进行查看大文件的操作,会带来不必要的麻烦:

首先因为我们需要把文件拷贝到输入输出流,这需要花费很长时间,这个过程会占用机器资源;

其次,本身文件会读取到内存中,这时内存被大量占用,很危险,这可能导致其他应用内存不足。因此我们需要一些不用加载整个文件,就能查看文件内容的指令。

more

more可以帮助我们读取文件但不需要读取整个文件到内存中。本身more的定位是一个阅读过滤器比如你在more里除了可以向下翻页还可以输入一段文本进行搜索。

如上图所示我在more查看一个 nginx 日志后,先输入一个/然后输入192.168看到的结果。more帮我找到了192.168所在的位置,然后又帮我定位到了这个位置。整个过程 more 指令只读取我们需要的部分到内存中。

less

less是一个和more功能差不多的工具打开man能够看到less的介绍上写着自己是more的反义词opposite of more。这样你可以看出linux生态其实也是很自由的一个生态在这里创造工具也可以按照自己的喜好写文档。less支持向上翻页这个功能more是做不到的。所以现在less用得更多一些。

head/tail

head和tail是一组它们用来读取一个文件的头部 N 行或者尾部 N 行。比如一个线上的大日志文件,当线上出了 bug服务暂停的时候我们就可以用tail -n 1000去查看最后的 1000 行日志文件,寻找导致服务异常的原因。

另一个比较重要的用法是如果你想看一个实时的nginx日志可以使用tail -f 文件名这样你会看到用户的请求不断进来。查一下man你会发现-f是 follow 的意思,就是文件追加的内容会跟随输出到标准输出流。

grep

有时候你需要查看一个指定ip的nginx日志或者查看一段时间内的nginx日志。如果不想用less和more进入文件中去查看就可以用grep命令。Linux 的文件命名风格都很短,所以也影响了很多人,比如之前我看到过一个大牛的程序,变量名从来不超过 5 个字母,而且都有意义。

grep 这个词,我们分成三段来看,是 g|re|p。

g 就是 global全局 re 就是 regular expression正则表达式 p 就是 pattern模式。

所以这个指令的作用是通过正则表达式全局搜索一个文件找到匹配的模式。我觉得这种命名真的很牛软件命名也是一个世纪难题grep这个名字不但发音不错而且很有含义又避免了名字过长方便记忆。

下面我们举两个例子看看 grep 的用法:

例 1查找 ip 地址

我们可以通过grep命令定位某个ip地址的用户都做了什么事情如下图所示

例 2查找时间段的日志

我们可以通过 grep 命令查找某个时间段内用户都做了什么事情。如下图所示,你可以看到在某个 5 分钟内所有用户的访问情况。

查找文件

用户经常还会有一种诉求,就是查找文件。

之前我们使用过一个which指令这个指令可以查询一个指令文件所在的位置比如which grep会你会看到grep指令被安装的位置是/usr/bin。但是我们还需要一个更加通用的指令查找文件也就是 find 指令。

find

find 指令帮助我们在文件系统中查找文件。 比如我们如果想要查找所有.txt 扩展名的文件可以使用find / -iname "*.txt"-iname这个参数是用来匹配查找的i 字母代表忽略大小写,这里也可以用-name替代。输入这条指令你会看到不断查找文件如下图所示

总结

这节课我们学习了很多指令,不知道你记住了多少?最后,我们再一起复习一下。

pwd指令查看工作目录。 cd指令切换工作目录。 which指令查找一个执行文件所在的路径。 ls显示文件信息。 rm删除文件。 touch修改一个文件的时间戳如果文件不存在会触发创建文件。 vi和nano可以用来编辑文件。 cat查看完成的文件适合小型文件。 moreless查看一个文件但是只读取用户看到的内容到内存因此消耗资源较少适合在服务器上看日志。 headtail可以用来看文件的头和尾。 grep指令搜索文件内容。 find指令全局查找文件。

在这里我再强调一个指令即man指令它是所有指令的手册所以你一定要多多运用熟练掌握。另外一个指令通常有非常多的参数但都需要用man指令去仔细研究。

那么通过这节课的学习你现在可以来回答本节关联的面试题目rm / -rf的作用是

老规矩,请你先在脑海里先思考你的答案,并把你的思考写在留言区,然后再来看我接下来的分析。

【解析】

/是文件系统根目录; rm是删除指令 -r是 recursive递归 -f是 force强制遇到只读文件也不提示直接删除。

所以rm -rf /就是删除整个文件系统上的所有文件,而且不用给用户提示。