解析:
/dev/null:代表空设备文件
> :代表重定向到哪里,例如:echo "123" > /home/123.txt
1 :表示stdout标准输出,系统默认值是1,所以">"等同于"1>"
2 :表示stderr标准错误&
& :表示等同于的意思,2>&1,表示2的输出重定向等同于1
在shell中,每个进程都和三个系统文件 相关联:标准输入stdin,标准输出stdout、标准错误stderr,三个系统文件的文件描述符分别为0,1、2。
command > /dev/null 2>&1 语句含义:
> /dev/null : 表示标准输出重定向到空设备文件
2> &1 :标准错误输出重定向(等同于)标准输出
总的来说就是:将标准输出stdin重定向到/dev/null文件,即输出内容不打印到屏幕上,而是输出到/dev/null文件中。 2>&1 是将标准出错重定向到标准输出,这里的标准输出已经重定向到了/dev/null文件,即将标准出错也输出到/dev/null文件中。即 >/dev/null 2>&1 相当于 1>/dev/null 2>/dev/null ,不过两者也存在区别
两者的区别:
- command >file 2>file:stdout和stderr都直接送往文件 a ,a文件会被打开两遍,由此导致stdout和stderr互相覆盖。
- command >file 2>&1 :stdout直接送往文件a ,stderr是继承了FD1的管道之后,再被送往文件a 。a文件只被打开一遍,就是FD1将其打开。
- command >file 2>file相当于使用了FD1、FD2两个互相竞争使用文件 a 的管道;
- command>filel 2>&1 只使用了一个管道FD1,但已经包括了stdout和stderr。
从IO效率上来讲,command >a 2>&1的效率更高。
下面通过一个例子来展示2>&1的效果:
$ cat test.sh
t
date
test.sh脚本中包含两个命令:
1、(t)是一个不存在的命令,执行会报错,默认情况下,错误会输出到stderr。
2、(date)则能正确执行,并且输出时间信息,默认输出到stdout
$sh test.sh > test1.log
./test.sh: line 1: t: command not found
$ cat test1.log
Wed Jul 10 21:12:02 CST 2013
(date)的执行结果被重定向到test1.log文件中,而(t)无法执行的命令错误则只打印在屏幕上。
$ sh test.sh > test2.log 2>&1
$ cat test2.log
./test.sh: line 1: t: command not found
Tue Oct 9 20:53:44 CST 2007
(date)和(t)的执行结果都被重定向到test2.log文件中。
试想一下1与&1代表什么?
2>1
2>代表标准错误重定向,1代表将标准错误重定向到一个文件1,而不代表标准输出;
2>&1
2>代表标准错误重定向,&1就代表标准输出stdout了,就变成将标准错误重定向到标准输出。
测试:
ls xx >out.txt 2>1测试,没有xx这个文件的标准错误输出到了文件1中,out.txt文件是空的;假如文件1和out.txt不存在,系统会自动创建;
stderr输出到文件1.png
ls xx >out1.txt 2>&1测试,没有文件1生成,没有xx这个标准错误输出在out1.txt文件中;
stderr输出到文件out1.txt.png
为何2>&1要写在后面?
command > file 2>&1
首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出的行为,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中。
command 2>&1 >file
2>&1 标准错误拷贝了标准输出的行为,但此时标准输出还是在终端。>file 后输出才被重定向到file,但标准错误仍然保持在终端。
用strace可以看到:
- command > file 2>&1
这个命令中实现重定向的关键系统调用序列是:
open(file) == 3
dup2(3,1)
dup2(1,2)
- command 2>&1 >file
这个命令中实现重定向的关键系统调用序列是:
dup2(1,2)
open(file) == 3
dup2(3,1)
可以考虑一下不同的dup2()调用序列会产生怎样的文件共享结构。参考APUE 3.10, 3.12
网友评论