我们需要树立一个观念,在Linux中, 一切皆文件,这对于以后理解Linux和Linux编程有很大的好处。
重定向
熟悉Linux的命令行操作后
如:
ls -l
会以列表方式将文件和目录的信息输出到屏幕上,但其实“屏幕”的说法并不准确,准确来说应该是标准输出
对于一个复杂的服务程序,可能会产生大量的日志,如果这些日志直接输出到屏幕上,不利于维护。
而对于长期运行的服务,我们更希望将日志保存在文件中,而不是直接输出到屏幕上。
如果从C语言的角度来看:
- 输出到标准输出:printf
- 输出到文件:fopen、fwrite等文件操作函数
但是以上是两套函数,相互割裂的。
而Linux提供了灵活的重定向机制,使得我们可以自己选择将本应该输出到标准输出的内容,重定向到指定文件。
shell中,提供了语法上的支持:
如:我们使用
ls -l
查看当前目录文件:
可以看到,文件目录打印到了屏幕上之后:
我们使用:
ls -l > 2.txt
用vim查看它:
vim 2.txt
可以看到:
2.txt中的内容就是我们刚刚向屏幕打印的内容。
以上就是一个重定向的例子,将本应该输出到标准输出的内容,输出到2.txt文件中。
重定义详解
了解重定义,要先了解三个概念:
- 标准输入:一般是键盘
- 标准输出:一般是控制台屏幕
- 标准错误:一般是控制台屏幕
实际上,标准输入、标准输出、标准错误本质都可以看做是文件
重定向过程,不仅可以输入重定向
以下为重定向的一些技巧
- 使用">" 会覆盖上一次的内容
- 使用">>" 不会覆盖原有内容,而是追加
- 使用"<" 会将内容当做标准输入
- 使用"<<"
输入重定向"<"
我们以adduser命令为例。
如果我们使用adduser命令,会交互式的填写很多项信息,然后完成用户的创建。
如果有一天,我们不方便交互式的输入信息,而是希望一口气输入完成,比如从文件中获取内容进行输入,我们就可以使用<
技巧
我们先来手动的交互式创建一个账户:
sudo adduser kongbai
我们成功的添加了一个名叫kongbai的账户
但是我们还可以这样子,先准备一个叫myinput.txt的文件,里面的内容为:
12345
12345
kongbai
NULL
123456789
123456
Kong
具体操作为:
vim myinput.txt
输入内容,然后保存退出。(vim的一些使用方法可看我往期的文章,,类似于vi的使用)
然后我们通过一下方式来使用adduser
sudo adduser kong <myinput.txt
以上命令,会将muinput.txt的内容当做标准输入传递给adduser。也就是说一口气就将所有的内容输入到adduser中了。结果如下:
"<<"
通过以上的例子我们知道了,我们可以只给使用者一个文件和一条命令。就可以保证运行结果是稳定的,而不会出现人为的输入错误。
但是对于额外的文件,依然显得不够"内聚"。
这时候就可以看"<<"的用处了。如以下例子:
sudo adduser kong1 << MAYDAY
> 12345
> 12345
> kong1
>NULL
>123456789
> 1234
> 123
> MAYDAY
我们也可以看到,创建了一个新的用户,以上的"<<“其实是接“自定义的结束符号”,当”<<"重定向后,键盘输入的内容,会被当
做输入,直到遇到自定义的结束符号为止,而这里MAYDAY就是结束符号。
重定向的应用
重定向有以下几点常见应用:
- 打印日志:将程序的标准输出,输出到文件,方便查看
- 简化修改配置文件的过程
- 忽略不必要的输出,前提是使用"/dev/null"文件
/dev/null文件很特殊,被称为"信息黑洞",它是一个空文件,可以接受所有的输入,但是所有的输入都会被丢弃。
我们查看这个文件的内容:
sudo vim /dev/null
发现的确是空的
接着我们向里面输入内容
sudo echo "hello">/dev/null
之后打开文件:
sudo vim /dev/null
发现里面还是空的
这验证了我们之前的说法,/dev/null可以接受输入,但所有的输入都将被丢弃,大家可以尝试向其输入任何的内容,之后验证其内容是否被改变。
那这个文件,又有什么用呢?
大家可以回想一下我们刚刚的例子,既然它可以接受所有的输入并且丢弃所有的输入,那不就代表,我们可以将所有我们不想要的垃圾信息配合重定向输入到这个文件中
,这样子就到达了过滤信息的目的。
小知识
对于长期运行的程序,会占据我们的控制台“shell”输入,不方便。
Linux的shell提供了“后台运行功能”(在命令的最后加上一个&符号即可)
如:
gedit&
管道
在Linux中,单个命令的功能很单一
举个例子,在Linux中是没有显示当前目录下的所有文件和目录的命令的,
但是却有显示当前目录下的所有文件和目录的命令ls(),也有统计数字的命令(wc)。
Linux提供的管到机制,可以组合命令
如:
ls|wc
可以将ls的文件输出输入到wc中,这样就是实现了想要的功能。
管道的语法非常的简单就是
命令1|命令2
管道发明实现了所谓的工具模块化,一个命令只实现一个功能, 但可以通过命令组合来实现想要的命令。