[RHEL]-9-终端数据重定向

引言

这篇文章主要讲解终端下常用的文件描述符的作用,使用这些文件描述符实现终端数据重定向。

文章目录

0×1.什么是文件描述符

Linux启动后,会默认分配三种文件描述符,分别为:标准输入(代号0),正确输出(代号1)1,错误输出(代号2) ;

当我们执行一条命令时,首先需要从键盘输入,这个输入就是标准输入,然后命令执行,根据执行的结果,如果命令正确执行,那么就将执行结果返回到屏幕上打印出来,这个就是正确输出(也叫标准输出),如果命令执行报错,会将报错信息输出到屏幕,这个输出就是错误输出;

在我们使用shell执行命令的时候,有时并不希望执行结果返回到屏幕上,而是储存到某个文件中,这时就可以配合系统内定的文件描述符将输出重定向到指定位置;

比较常用的文件描述符与重定向符号如下:

标准输入(stdin) :代码为0,使用<或<<;
标准输出(stdiout) :代码为1,使用>或>>;
错误输出(stderr) :代码为2,使用2>或2>>;

除了上面的三种描述符外,用户还能够自定义描述符,代号从3~N(N为ulimit -n命令的执行结果),了解了这些基础知识后,下面来看几个实例。

0×2.输出重定向

打开终端,终端所在目录下有一个文件"a",但没有文件"b",现在用ls同时访问这两个文件,屏幕上会输出a文件的全名,同时打印出一个b文件不存在的错误,如下:

					#新建文件a,文件b是不存在的
					www@qingsword.com:~$ touch a
					www@qingsword.com:~$ ls a b
					ls: 无法访问'b': 没有那个文件或目录
					a

					#现在我们将ls的输出信息,通过标准输出重定向(标准输出重定向的完整写法是"1>",但系统默认是标准输出重定向,所以可以省略1不写),写入到文件stdin.txt文件中,从输出可以看到,屏幕上仅打印出了"错误输出"信息,而"标准输出"信息被保存到了stdin.txt文件中
					www@qingsword.com:~$ ls a b > stdin.txt
					ls: 无法访问'b': 没有那个文件或目录
					www@qingsword.com:~$ cat stdin.txt 
					a

					#那么如果想将"错误输出"也重定向到某个文件中,就需要使用"2>",如下,现在标准输出显示到了屏幕上,而错误输出被重定向写入了stderr.txt文件中
					www@qingsword.com:~$ ls a b 2> stderr.txt
					a
					www@qingsword.com:~$ cat stderr.txt 
					ls: 无法访问'b': 没有那个文件或目录

					#如果想让标准输出和错误输出全部重定向,可以如下,这样就将命令执行后的标准输出保存到了stdin.txt,将错误输出保存到了stderr.txt
					www@qingsword.com:~$ ls a b > stdin.txt 2> stderr.txt

					www@qingsword.com:~$ cat stdin.txt stderr.txt 
					a
					ls: 无法访问'b': 没有那个文件或目录

					#除了单个>外,两个>>表示重定向内容的追加写入,例如,在上面实例的基础上
					www@qingsword.com:~$ ls a b >> stdin.txt 2>> stderr.txt

					#命令执行的结果被追加到了上次执行结果的下方,而不同于单个>的覆盖操作
					www@qingsword.com:~$ cat std*
					ls: 无法访问'b': 没有那个文件或目录
					ls: 无法访问'b': 没有那个文件或目录
					a
					a

					#如果想将输入和输出信息屏蔽(不打印也不保存到文件),可以使用下面的方法,"&-"就相当于/dev/null文件,也可以使用/dev/null替换"&-"效果相同(如果只是想屏幕其中一种输出,例如 ls a b 2>&-,仅屏蔽错误输出)
					www@qingsword.com:~$ ls a b >&- 2>&-
					#或
					www@qingsword.com:~$ ls a b &>/dev/null
					

Ps:shell遇到>操作符,首先判断符号右边文件是否存在,如果存在就先删除,并且创建新文件,不存在直接创建, 如果左边命令执行失败,右边文件会变成空文件,否则,向文件中写入数据;>>操作符右边文件不存在则创建,如果存在则以添加方式打开文件追加内容。

0×3.输入重定向

这种重定向在实际使用中比较少见,它可以将命令默认从键盘获得的输入改成从文件或设备获得输入,例如:

					#首先cat从键盘获得数据(标准输入),将数据重定向写入stdin.txt文件
					www@qingsword.com:~$ cat > stdin.txt
					Welcome to my website
					www.qingsword.com #按ctrl+d结束键盘输入

					www@qingsword.com:~$ cat stdin.txt 
					Welcome to my website
					www.qingsword.com

					#现在创建一个新文件infile.txt,写入"Enjoy yourself!"
					www@qingsword.com:~$ echo "Enjoy yourself!" > infile.txt

					#将infile.txt文件中的内容作为cat命令的输入,然后追加到stdin.txt内容的末尾
					www@qingsword.com:~$ cat >> stdin.txt < infile.txt

					#等同于cat stdin.txt
					www@qingsword.com:~$ cat < stdin.txt 
					Welcome to my website
					www.qingsword.com
					Enjoy yourself!

					#当用户输入exit回车后,结束输入,并将用户的输入重定向写入到cat.txt文件中
					www@qingsword.com:~$ cat > cat.txt << exit
					> 这里是输入的内容
					> 第二行
					> exit

					www@qingsword.com:~$ cat cat.txt 
					这里是输入的内容
					第二行
					

0×4.绑定重定向

在上面的实例中,每个重定向仅适用于当前执行的命令,而使用绑定重定向能够让绑定的重定向适用于后面所有的命令,请看下面的实例:

					#首先将11绑定成标准输出重定向,用于恢复
					qing@qingsword:~/test$ exec 11>&1

					#绑定标准输出重定向,让之后所有的标准输出,都重定向追加写入到stdin.txt文件中(stdin.txt文件最好使用绝对路径),之后所有命令的标准输出都不会出现在屏幕上
					qing@qingsword:~/test$ exec 1>>stdin.txt 
					qing@qingsword:~/test$ ls a
					qing@qingsword:~/test$ more stdin.txt

					#恢复绑定,将标准输出重定向绑定成上面备份的11
					qing@qingsword:~/test$ exec 1>&11
					#删除11提示符
					qing@qingsword:~/test$ exec 11>&-

					#查看一下标准输出是否被保存到了文件中,测试成功
					qing@qingsword:~/test$ cat stdin.txt 
					a
					a