【Linux系统】------ 基本指令(三)
- [1 一切皆文件](#1 一切皆文件)
- [2 重定向操作](#2 重定向操作)
-
- [2.1 初始重定向](#2.1 初始重定向)
- [2.2 重定向的妙用](#2.2 重定向的妙用)
- [2.3 追加重定向](#2.3 追加重定向)
- [2.4 输入重定向](#2.4 输入重定向)
- [2.5 一切皆文件与重定向结合](#2.5 一切皆文件与重定向结合)
- [3 Linux 中的文件类型](#3 Linux 中的文件类型)
- [4 日志](#4 日志)
- [5 「more」命令](#5 「more」命令)
- [6 「less」命令](#6 「less」命令)
- [7 「head」与「tail」](#7 「head」与「tail」)
-
- [7.1 查看文件开头和结尾](#7.1 查看文件开头和结尾)
- [7.2 查看文件中间部分](#7.2 查看文件中间部分)
1 一切皆文件
我们先认识一个知识点:
- 在 L i n u x Linux Linux 中,一切皆文件!
在 Linux 系统中,一切皆文件,这句话理解呢?
Linux 系统不仅仅会把我们新建的 「.c」、「.cpp」、「.txt」、可执行程序当做文件,也将磁盘、网卡、显卡、键盘、鼠标、显示器这样的设备,在系统层面设计成了文件,以文件的形式显示来呈现。
这一点我们简单有个概念就行,暂时不考虑为什么,在今后的学习中我们会不断深入理解这个概念。
基于一切皆文件这个知识点,我们现在推导出一些结论出来:
- Linux 下一切皆文件,而我们现在最常见的文件就是我们自己新建的文件,这一点是我们最好理解的
- 除此之外,在 Linux 系统中还有三种比较重要的文件,我们称之为
设备文件
- 键盘
- 显示器
- 显示器
这里两个显示器先不作区分
一般一个程序启动时,它默认会打开这三个设备文件。
我们简单来理解一下:
在我们之前学习 C/C++ 时,可以直接用 printf/scanf、cin/cout 进行输入输出显示。我们以输出为例,当我们在 printf(cin) 时,本质是向这个显示器进行打印。
因为 C/C++ 程序也要在 Linux 系统下跑,而 Linux 中一切皆文件,显示器也是文件,我们可以认为输入输出本质其实是文件操作。
以前我们说从标准输入获取内容,从键盘获取内容,从显示器进行打印,这个理解每没错,但是它属于语言体系下的,是语言的话语体系下的表示方式。但是这种表述方式并不能让我们更深刻地区了解语言和系统。而在一切皆文件的原则性指导下,显示器和键盘都是文件,我们以前最基础的 cin/cout 本质都是文件操作
。
可是按照我们的认识,文件操作:对任何文件进行操作,都必须先打开这个文件。之前学习C语言的时候(详情请看【C语言】------ 文件操作(上)和【C语言】------ 文件操作(下)),每次操作文件前都要用 fopen 将文件打开,操作完成之后再用 fclose 将文件关闭。那换言之我们对键盘显示器这样的文件,在被我们访问时也要被我们打开,我们才能对他进行对应的操作,因为他们也是文件。
可是现在的问题是,我们之前学习C语言时,我们没有打开什么显示器的文件就能向显示器中打印内容。为什么没有打开文件就能直接打印呢?因为系统在启动我们的程序时,系统默认帮我们打开了
。Windows 下就是 Windows 系统帮我们打开;Linux 下就是 Linux 系统帮我们打开。
系统默认帮我们打开的三个文件
stdin 对应的是键盘,stdout 和 stderr 对应的是两个显示器,他们的类型是 FILE*
小伙伴们不要认为我们的代码写完了就完了,代码写完了还有编译器,操作系统未来在加载我们这个程序时还有操作系统呢,所以我们写的程序最后运行起来系统是要作很多工作的:比如系统帮我们把上述三个设备文件给打开。
我们自己写好了一个程序,将程序编程二进制代码编好了,那么当我们的程序最后在链接时,我们可以理解成系统给我们自己的代码在 main 函数之前加了一部分代码,这其中就包括打开这三个设备文件。程序在执行时,我们说 main 函数是入口,但是没说系统执行时只能从 main 函数开始跑
,只是我们的代码是从 main 函数开始跑而已,系统在调用 main 函数之前会先去执行一部分指令。
为什么系统要帮我们打开呢?
其实答案很简单:我们编写一个程序,要么就是将数据交给程序,让程序帮忙做计算吗,计算完后再将结果显示出来。系统默认打开三个设备文件是为了让用户可以直接输入直接显示,方便操作 。如果系统不打开,那就要用户自己去打开,非常麻烦。
那为什么不打开其他文件呢?
因为默认打开三个就够用了,用户需要打开其他的,自己打开就行了
2 重定向操作
2.1 初始重定向
我们只看操作
「echo 'hello linux'」指令,翻译过来就是将 'hello linux' 字符串写到了显示器文件里,所以我们才在显示器看到了
我们可以把他重定向
到一个文件『hello.txt』中
我们看到,我们加了一个 「>」,本来应该往显示器打印的内容现在不再往显示器中打了,那 'hello linux' 字符串在哪呢?它在『hello.txt』文件中(文件不存在则新建)
我们用「cat」指令打印『hello.txt』中的内容:
此时,本来应该写入到显示器文件中的内容写入到了一个普通文件中,这个工作我们叫做输出重定向。
我们再进行一次重定向操作:
发现『hello.txt』的内容被覆盖了。
总结一下:
- 如果文件不存在,则新建一个文件
- 如果文件存在,则
先清空再写入
2.2 重定向的妙用
既然如此,是不是意味着我们往后新建文件时,可以不用「touch」命令呢?
还真是
直接: 「>」『文件名』 就可以创建一个新文件!
因为输出重定向默认操作就是如果不存在就先创建。现在,我左侧什么都没有,也就是我什么都不写,但即使我什么都不,你也要先给我把文件给创建出来
注:「>」只能新建普通文件,无法新建目录
同理,对于一个已经存在的文件,我们想将其清空也能用重定向
总结:我们可以用重定向来新建或者清空文件。
2.3 追加重定向
如果我们不想覆盖式写入,而是追加式写入,又该输入什么指令呢?
这时需要用 「>>」
我们将这种重定向称为追加重定向
这里我们来回顾一下:不知道大家还记不记得之前学习C语言时,打开一个文件有多种打开方式,而「>」就相当于以『w+』的形式打开文件,「>>」相当于以『a+』的方式打开文件。
因此,重定向操作看起来是 Linux 的操作,其实它是C语言的操作
2.4 输入重定向
我们下面再介绍一种重定向:
我们「cat」『文件名』
会将文件中的内容写入显示器文件 中,但如果我们只输入「cat」命令呢?
这时命令行就会卡住,专业术语叫阻塞
此时,我们输入什么,显示器就回显什么
为什么呢?
「cat」默认是从键盘文件中读内容,然后把读到的内容写入到显示器文件中 。所以只输入「cat」命令,就是我从键盘输什么,它就给我打印什么
之前,我们打印文件内容都是「cat」 『文件名』
,其实「cat」命令还可以这样使用:「cat」「<」 『文件名』
前面我们说「cat」默认是从键盘文件读取的,而「cat」「<」 『文件名』
就是让「cat」不在键盘文件中读,而是从定向到指定的文件中读。「cat」「<」 『文件名』
这种写法一样能将指定文件的内容读出来
那「cat」 『文件名』
和「cat」「<」 『文件名』
有什么区别呢?
虽然他们的结果是一样的,但是还是有区别的。但这里不过多解释,需要我们学习更多内容才能理解他们的区别。
现在我们只需要理解:「cat」本来是从键盘文件中读数据,用 「<」 输入重定向后,从指定文件中读数据
2.5 一切皆文件与重定向结合
文章开头我们说在 Linux 系统中一切皆文件,那我们有一个大胆的想法:终端的本质在 Linux 系统中就是一个文件
一起来验证一下:
我们平时登录 Linux 服务器时,实际上我们终端对应的文件一般都在 /dev/pts
路径下(dev 即 device)
当我们打开一个对应的设备时,它就会在 /dev/pts 目录下帮我们新建一个文件:它的文件名是 0,它的类型是以 「c」 开头
在 Linux 中,我们把以 「c」 开头的文件叫做字符文件
。
我们再打开一个终端:
会发现两个终端都多了『1』 文件
如果我们再不断打开终端,还会有『2』、『3』、『4』文件
每个终端本质都是一个文件,上面打开的两个终端分别是 『0』 和 『1』 号文件
既然打印的本质就是向显示器文件写入,而重定向的本质就是向文件写入,那当然也可以向我们的设备文件(『0』、『1』、『2』文件)中写入。比如在『1』文件对应的终端中向『1』文件中写,写给我自己
又比如:我还可以在『1』文件对应的终端中向『0』文件中写
所以为什么我们自己的「echo」命令、「ls」 命令,它打印内容的时候默认都往自己这个显示器上打呢?我们输入指令的时候,默认向我这个终端对应的文件中(『0』、『1』、『2』文件)去写
,将执行结果写入到对应的显示器文件中,我们就能在对应显示器上看到结果了。
我们最终印证了一个结论:终端的本质在 Linux 系统里就是一个文件(/dev/pts/xxx)
终端也是文件,Linux 系统把所有的东西都干成文件。未来我们在 Linux 系统中做的操作,最后都会转换成对文件操作。
3 Linux 中的文件类型
先说结论:Linux 看文件类型不看文件后缀。也就是说 Linux 不看「.txt」、「.jpg」、「.cpp」 等文件后缀。Linux 看的是「ll」命令显示出来的文件属性中的第一列字符
我们简单了解一下 Linux 中的文件类型
- 「-」开头:普通文件
- 「dl」开头:目录文件
- 「c」开头:字符文件(键盘、显示器、终端等)
- 「b」开头:块设备文件(磁盘)
- 「l」开头:链接文件
- 「p」开头:管道文件
字符文件有一个特点:文本处理有严格的顺序,或者说输入的数据具有顺序性
。比如说我输入 hello 是有意义的;而输入 olleh ,乱序了,是没有意义的。
块设备文件:磁盘就是一个块设备文件,磁盘所对应的文件是 vda,路径是 /dev/vda。块设备支持随机读写。
这就相当于 Windows 系统中的磁盘(不是C盘E盘,是一块物理盘,一块薄板)
那前面说 Linux 一起皆文件,我是不是可以往『vda』文件中写数据呢?
如果往里面写数据,类似于直接把 Windows 中的物理盘直接打开了,直接向物理盘中写数据谁都不知道数据写哪了。相当于绕过了 Linux 系统,本来我可以通过「touch」 命令创建,你现在直接把『vda』打开往里写。这样可能会将磁盘中数据覆盖,整个操作系统可能就有问题了。所以不能往『vda』写数据。
普通文件都有哪些呢?文本文件、可执行文件、库文件、图片文件、视频文件等等,大部分我们平时用到的文件都是普通文件
,这点和 Windows 的差别挺大的
既然 Linux 不以文件后缀作为文件区分类型,那我们普通文件可以不带后缀(.cpp/.txt/.jpg),甚至乱带后缀吗?
不可以!
虽然 Linux 系统不以文件后缀来区分文件,但并不代表普通文件不用后缀。
这有点矛盾,什么意思呢?
虽然 Linux 系统不关心文件后缀,但不代表工具不关心后缀
。如 gcc编译器:gcc 不是系统,它只是一个简单的编译器,它要编译 C代码,必须是 .c 后缀的文件才可以编译。
同时 Linux 系统不关心后缀,不代表禁止使用后缀。不关心的意思是你想用就用,不用就不用
所以后面创建文件时,该 .c 就 .c 该 .txt 就 .txt,只不过系统会将后缀当做文件名的一部分。
4 日志
作为一名标准的程序员,差日志是一件很常见的事情。这里我们就简单讲一下日志
Linux 系统中,对应的日志放在 syslog(ubunto) / messages(centos)文件下,路径如下:/var/log/syslog(messages)
我们用「cat」指令来看下日志中的内容
日志会将我们操作的痕迹给记录下来。是的,我们在 Linux 下做的操作,都是会被记录下来的。
一般的日志都会记录下操作时间
、操作内容
、操作用户
等信息。
日志的意义是:系统出问题方便程序员去排查
在软件领域,任何大型项目,必定要有日志。因为用户使用你这个项目,未来要是这个项目挂掉了,我们排查错误时,要去翻看日志,看用户进行了那些操作导致项目挂了,以进行修改。
那 Linux 有日志,Windows 有日志吗?肯定也是有的,在 C盘 中。
其实 Linux、Windows、手机等在进行应用程序运行时,在本地都会一直形成日志信息的,只不过日志的形式不太一样。这就是为什么电脑、手机等用的时间久了,内存会稍微减少的原因。
但这个日志不断形成,最后信息越来越多,系统抗不住怎么办?不用担心,一般日志写的差不多了,会把文件进行切片;会进行覆盖写;或者日志做个备注;又或者偷偷上传至后台,它自己再拿日志做分析,检查自己的软件有什么错误,检测完后再删掉
5 「more」命令
语法:「more」 [选项][文件名]
功能:功能类似「cat」,逐页显示文本内容
命令行选项-n:对输出的所有行编号
q:退出 「more」
日志文件往往很大,我们不想一次性全部打印出来怎么办呢?这时就可以用「more」指令。「more」指令先打印一屏幕 的内容,后可以通过按住回车键 不断将文件往下翻,查看文件后面的内容
不会将内容一次性打出来,只打印一屏幕。
按住回车键就可以逐行下翻,继续看下面的内容
如果想退出 阅读可以按Q键
同时「more」还支持搜索功能
为了方便演示,我们创建一个大文件『log.txt』,代码如下:cnt=0; while [ $cnt -le 1000 ]; do echo "hello $cnt"; let cnt++; done > log.txt
但是「more」不支持上翻,「more」只支持下翻。因此我们很少用「more」命令,因为有更好的「less」命令。
6 「less」命令
「less」工具也是对文件或其它输出进行分页显示的工具,应该说是 Linux 正统查看文件内容的工具,功能极其强大。
「less」的用法比起「more」更加的有弹性。使用「more」时,我们并没有办法向前面翻, 只能往后面看
但若使用了「less」时,就可以使用 [pageup][pagedown] 等按键的功能来往前往后翻看文件,更容易用来查看一个文件的内容!
除此之外,在「less」里头可以拥有更多的搜索功能,不止可以向下搜,也可以向上搜。
语法:「less」 [参数] 『文件』
功能:既有查看 目标文件的内容的功能,又有搜索功能。
命令行选项-i:忽略搜索时的大小写
-N:显示每行的行号
/字符串:向下搜索"字符串"的功能
?字符串:向上搜索"字符串"的功能
n:重复前一个搜索(与 / 或 ? 有关)
N:反向重复前一个搜索(与 / 或 ? 有关)
q:退出
「less」命令与「more」命令功能类似,但是「less」比「more」强的地方在于:「less」可以上翻也可以下翻
我们用「less」查看这个文件:
我们可以通过 ↑
键查看以前数据,↓
键查看之后数据;或者通过鼠标滚轮
也可以上下翻看数据。
同时「less」也支持查找功能,这里就不再演示了,用法与「more」一样
7 「head」与「tail」
7.1 查看文件开头和结尾
「head」与「tail」就像他们的名字一样浅显易懂,他们就是用来显示开头或结尾某个数量的文字区块,「head」用来显示文件的开头部分,「tail」用来显示文件的结尾部分
如:我们用「head」和「tail」来显示『log.txt』的开头和结尾部分
当然,我们也可以指定显示的行数
7.2 查看文件中间部分
那如果我先看文本中间部分的内容又该怎么办呢?
假设我们现在要看他 500-510 行
我们可以先把他前 510 行拿到,然后重定向到一个临时文件,在取这个临时文件的最后 10 行
可是这种做法太挫了,还要生成一个临时文件。
这里我们再提供一种方法,先看操作:
我们来理解一下
左侧head -510 log.txt
是一条命令,右侧tail -10
也是一条命令。左侧的命令的执行结果经过『 | 』,写到『 | 』这个临时文件中 。Linux 下一切皆文件,『 | 』也是文件,我们将『 | 』称为管道文件。右侧的命令再从管道文件中读取数据,再对其进行操作。
管道文件就行现实中的自来水管道一样,一段是进水的,一段是出水的。head -510 log.txt
就相当于进水,tail -10
就相当于出水
有了管道文件,一个命令的处理的结果,就可以经过管道交给下一个命令
。我们就可以用它来进行命令的相连,进行批量化的命令处理
学习了管道文件,我们还可以这样:
我们先把文件内容打印出来,写在第一个管道文件中;再取出第一个管道文件中的前 510 行放第二个管道中,再取第二个管道后 10 行放第三个管道中,最后在将第三个管道中的内容逆序打印出来
好啦,本期关于基本指令的知识就介绍到这里啦,希望本期博客能对你有所帮助。同时,如果有错误的地方请多多指正,让我们在 Linux 的学习路上一起进步!