shell脚本中>/dev/null 2>&1具体说明

简述:

shell脚本中经常会出现在一个命令cmd后面跟着 >/dev/null 2>&1,本文详细理清一下shell重定向

为什么需要重定向?

shell脚本在执行的过程中,会有一些系统打印,有的是标准输出,有的是错误输出,这里的错误输出不一定是指shell脚本有问题,而是系统打印的一些异常或者错误输出,不影响系统运行的。一般shell脚本都是相较复杂多指令的。这里有个问题,C语言程序中调用shell脚本,一般是用 system 来调用,这里就有一个问题,system执行过程中,shell脚本是否顺利执行完毕,要看执行期间有没有被异常信号中断,如果出现异常信号,system调用的shell则会终止。

这里我们需要做的就是去掉system调用的shell脚本中的异常输出,这里就需要shell重定向输出了。

shell重定向

当执行shell命令时,会默认打开3个文件,每个文件有对应的文件描述符来方便我们使用:

类型文件描述符默认情况对应文件句柄位置
标准输入(standard input) 0 从键盘获得输入 /proc/self/fd/0
标准输出(standard output) 1 输出到屏幕(即控制台) /proc/self/fd/1
错误输出(error output) 2 输出到屏幕(即控制台) /proc/self/fd/2

 

 

 

 

我们可以看下具体信息

root@LEDE:/proc/392/fd# ls -all
dr-x------    2 root     root             0 Jul 23 10:36 .
dr-xr-xr-x    8 root     root             0 Jul 23 09:48 ..
lr-x------    1 root     root            64 Jul 23 10:36 0 -> /dev/ttyS0
l-wx------    1 root     root            64 Jul 23 10:36 1 -> /dev/ttyS0
lrwx------    1 root     root            64 Jul 23 10:36 10 -> /dev/tty
l-wx------    1 root     root            64 Jul 23 10:36 2 -> /dev/ttyS0

/dev/ttyS0对应的就是串行端口终端。

输出重定向

输出重定向的使用方式很简单,基本的一些命令如下:

命令介绍
command >filename 把标准输出重定向到新文件中
command 1>filename 同上
command >>filename 把标准输出追加到文件中
command 1>>filename 同上
command 2>filename 把标准错误重定向到新文件中
command 2>>filename 把标准错误追加到新文件中

 

 

 

 

 

 

我们使用>或者>>对输出进行重定向。符号的左边表示文件描述符, 如果没有的话表示1,也就是标准输出 ,符号的右边可以是一个文件,也可以是一个输出设备。当使用>时,会判断右边的文件存不存在,如果存在的话就先删除,然后创建一个新的文件,不存在的话则直接创建。但是当使用>>进行追加时,则不会删除原来已经存在的文件。

举例:

root@LEDE:/tmp# touch exist.txt
root@LEDE:/tmp# ls exist.txt notexist.txt 1>out
ls: notexist.txt: No such file or directory
root@LEDE:/tmp# cat out 
exist.txt
root@LEDE:/tmp# ls exist.txt notexist.txt 1>>out
ls: notexist.txt: No such file or directory
root@LEDE:/tmp# cat out 
exist.txt
exist.txt
root@LEDE:/tmp# ls exist.txt notexist.txt 2>err
exist.txt
root@LEDE:/tmp# cat err
ls: notexist.txt: No such file or directory
root@LEDE:/tmp# ls exist.txt notexist.txt >out 2>err
root@LEDE:/tmp# cat out 
exist.txt
root@LEDE:/tmp# cat err 
ls: notexist.txt: No such file or directory

输入重定向

对输入进行重定向的基本命令:

命令介绍
command <filename 以filename文件作为标准输入
command 0<filename 同上
command <<delimiter 从标准输入中读入,直到遇到delimiter分隔符

 

 

 

 

我们使用<对输入做重定向时, 如果符号左边没有写值,那么默认就是0。

请用cat进行试验。

/dev/null

手抄一段《linux shell脚本攻略》描述:

/dev/null是一个特殊的设备文件,这个文件接收到的任何数据都会被丢弃。因此,null这个设备通常也被称为位桶(bit bucket)或黑洞。

简单地理解就是,重定向操作给这个/dev/null文件的所有东西都会被丢弃。

因为这些文件描述符输出的字符串,总是会显示出来的。如果我们在shell编程的时候,操作到某一条命令的返回结果,我们不想要这个时候又不想让这个输出结果打印到屏幕上我们就可以重定向到/dev/null这个文件来,由/dev/null这个文件负责处理后事。

这个丢弃的结果又不能粗暴的认为是删除错误输出,这个操作是一个丢弃重定向输入输出的操作。

>filename 2>&1

1.2>&1,将错误输出绑定到标准输出上。由于此时的标准输出是默认值,也就是输出到屏幕,所以错误输出会输出到屏幕。

2.>filename, 将标准输出1重定向到filename中。

>/dev/null 2>&1 VS >/dev/null 2>/dev/null

首先command > file 2>file 的意思是将命令所产生的stdout标准输出信息和stderr错误的输出信息送到file 中。command > file 2>file 这样的写法,stdout和stderr都直接送到file中,file会被打开两次,这样stdout和stderr会互相覆盖,这样写相当使用了FD1和FD2两个同时去抢占file的管道。

而command >file 2>&1 这条命令就将stdout直接送向file,stderr 继承了FD1管道后,再被送往file,这种写法file文件只被打开了一次,即只使用了一个管道FD1就包括了stdout和stderr的内容。

从IO效率上,command >file 2>&1命令的效率要比command > file 2>file的命令效率高,所以在编写shell脚本时,我们较多时间使用command > file 2>&1的写法。

END

 

posted @ 2019-07-23 11:56  稀客  阅读(2822)  评论(0编辑  收藏  举报