《Ubuntu — 2>/dev/null和>/dev/null 2>&1和2>&1>/dev/null的区别》

1.区别

2>/dev/null

  意思就是把错误输出到“黑洞”。

>/dev/null 2>&1

  默认情况是1,也就是等同于1>/dev/null 2>&1。意思就是把标准输出重定向到“黑洞”,还把错误输出2重定向到标准输出1,也就是标准输出和错误输出都进了“黑洞”。

2>&1 >/dev/null

  意思就是把错误输出2重定向到标准出书1,也就是屏幕,标准输出进了“黑洞”,也就是标准输出进了黑洞,错误输出打印到屏幕。

  乍一看>/dev/null 2>&1和2>&1 >/dev/null应该是一样的效果。但是为什么会不一样呢?

  linux在执行shell命令之前,就会确定好所有的输入输出位置,并且从左到右依次执行重定向的命令。那么我们同样从左到右地来分析 2>&1>/dev/null :

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

  我们用一个表格来更好地说明这两条命令的区别:

  

  为什么要用重定向绑定,而不是像 >/dev/null 2>/dev/null?

  我们回到刚才介绍输出重定向的场景。我们尝试将标准输出和错误输出都定向到out文件中:

# ls a.txt b.txt >out 2>out# cat out
a.txt
�法访问b.txt:没有那个文件或目录

  出现了乱码,这是为啥呢?这是因为采用这种写法,标准输出和错误输出会抢占往out文件的管道,所以可能会导致输出内容的时候出现缺失、覆盖等情况。现在是出现了乱码,有时候也有可能出现只有error信息或者只有正常信息的情况。不管怎么说,采用这种写法,最后的情况是无法预估的。

  而且,由于out文件被打开了两次,两个文件描述符会抢占性的往文件中输出内容,所以整体 IO 效率不如 >/dev/null2>&1来得高。

2. 解释

2.1、文件描述符

Linux系统预留可三个文件描述符:0、1和2,他们的意义如下所示:

  • 0——标准输入(stdin)
  • 1——标准输出(stdout)
  • 2——标准错误(stderr)

标准输出——stdout

  假设:在当前目录下,有且只有一个文件名称为ljl.txt的文件,这时我们运行这个命令【ls ljl.txt】,就会获得一个标准输出stdout的输出结果:ljl.txt。

错误输出——stderr

  按照上面的假设,我们运行另一条命令【ls gss.txt】,这样我们就会获得一个标准错误stderr的输出结果“ls:无法访问gss.txt:没有那个文件或目录”。

 

 

 

2.2、重定向

  重定向的符号有两个:>或>>,两者的区别是:前者会先清空文件,然后再写入内容,后者会将重定向的内容追加到现有文件的尾部。举个例子:

(1)、重定向标准输出stdout

 

 

   如上图所示,对比没有添加重定向的操作,这条命令在使用之后并没有将123.txt打印到屏幕。在紧接的cat操作后,可以发现本来应该被输出的内容被记录到stdout.txt中。

(2)、重定向标准错误stderr

 

 

   如上图所示,文件描述符2,标准错误的重定向也是同样的原理被记录在了文件stderr.txt这个文件里面了。

2.2、重定向绑定

2>&1

  这条命令用到了重定向绑定,采用&可以将两个输出绑定在一起。这条命令的作用是错误输出将和标准输出同用一个文件描述符,说人话就是错误输出将会和标准输出输出到同一个地方。

 

posted @ 2020-03-23 11:38  一个不知道干嘛的小萌新  阅读(957)  评论(0编辑  收藏  举报