与处理标准输出一样,默认情况下,shell将命令的标准错误输出发送到屏幕上。除非重定向标准输出和标准错误输出中的某一个,否则不能区分命令的输出到底是标准输出还是标准错误输出。
文件描述符是程序发送输出和获取输入的地方。当执行一个程序时,运行该程序的进程打开了3个文件描述符,分别是:0(标准输入)、1(标准输出)和2(标准错误输出)。重定向输出符号(>)是1>的简写,它通知shell重定向标准输出。类似地,将重定向标准错误输出。
表8-2重定向操作符
操作符
含义
将标准输入重定向为文件filename
>filename
除非文件filename已存在并且设置了noclobber标记,否则标准输出将被重定向到文件filename;如果文件filename不存在且没有设置noclobber标记,那么重定向操作将创建该文件
>|filename
即使文件filename存在且设置了noclobber标记,仍将标准输出重定向到该文件
>>filename
除非文件filename已存在并且设置了noclobber标记,否则标准输出将被重定向到文件filename,并将内容添加到原文件的末尾;如果没有设置noclobber标记,并且文件filename不存在,那么将创建该文件
m
从文件描述符m复制标准输入
[n]>&m
从文件描述符m复制标准输出或者文件描述符n(如果命令中指定了n)
[n]
关闭标准输入或者文件描述符n(如果指定了n)
[n]>&-
关闭标准输出或者文件描述符n(如果指定了n)
[root@localhost ~]# cat x
cat: x: No such file or directory
[root@localhost ~]# cat y
this is y!
[root@localhost ~]# cat x y
cat: x: No such file or directory
this is y!
[root@localhost ~]# cat y x
this is y!
cat: x: No such file or directory
将命令的标准输出重定向时,发送到标准错误输出的输出将不受影响,仍然出现在屏幕上
[root@localhost ~]# cat x y > hold
cat: x: No such file or directory
[root@localhost ~]# cat hold
this is y!
当使用管道发送标准输出时,标准错误输出也不会受到影响
[root@localhost ~]# cat x y | grep y
cat: x: No such file or directory
this is y!
将标准输出和标准错误输出重定向到不同的文件中。符号2>告诉shell将标准错误输出(文件描述符为2)重定向到的具体位置。1>告诉shell将标准输出(文件描述符为1)重定向到的具体位置。可以使用>代替1>。
[root@localhost ~]# cat x y 1>hold1 2>hold2
[root@localhost ~]# cat hold1
this is y!
[root@localhost ~]# cat hold2
cat: x: No such file or directory
复制文件描述符在下一个示例中,1>将标准输出重定向到文件hold。然后,2>&1声明文件描述符2为文件描述符1的副本。这样做的结果是,标准输出和标准错误输出均被重定向到文件hold中
[root@localhost ~]# cat x y 1>hold 2>&1
[root@localhost ~]# cat hold
cat: x: No such file or directory
this is y!
在这个示例中,1>hold放在了2>&1的前面。如果将它们的顺序颠倒的话,在标准输出重定向到文件hold之前,标准错误输出就已经复制了标准输出的一个副本。这样一来,就只有标准输出被重定向到文件hold
[root@localhost ~]# cat x y 2>&1 1>hold
cat: x: No such file or directory
[root@localhost ~]# cat hold
this is y!
发送错误到标准错误输出还可以使用1>&2将命令的标准输出重定向到标准错误输出。shell脚本中经常使用这项技术将echo的输出发送到标准错误输出。在下面的脚本中,第1个echo命令的标准输出被重定向到标准错误输出:
[root@localhost ~]# echo This is an error message. 1>&2
This is an error message.
对最后一个的解释,更多具体的为:
ls > dirlist 2>&1(等价于ls 1 > dirlist 2>&1,标准输出1被定向到文件dirlist,标准错误输出2拷贝了&1(标准输出1),这样实际标准错误输出2也被定向到了dirlist。)directs both standard output and standard error to the file dirlist,(结果标准输出1和标准错误输出2都被定向到文件dirlist) while the command
ls 2>&1 > dirlist(等价于ls 2 > &1 1>dirlist ,标准错误输出2被复制到了标准输出1,完成以后标准输出1被定向到文件dirlist)
directs only the standard output to file dirlist, because the standard error was duplicated as standard output before the standard output was redirected to dirlist(结果只有标准输出被定向到文件dirlist,因为在此之前,标准错误输出2已经被复制到了标准输出1上)。
command >out.file2>&1 &
command >out.file是将command的输出重定向到out.file文件,即输出内容不打印到屏幕上,而是输出到out.file文件中。2>&1是将标准出错重定向到标准输出,这里的标准输出已经重定向到了out.file文件,即将标准出错也输出到out.file文件中。最后一个&, 是让该命令在后台执行
2>1代表什么,2与>结合代表错误重定向,而1则代表错误重定向到一个文件1,而不代表标准输出;换成2>&1,&与1结合就代表标准输出了,就变成错误重定向到标准输出。
ls 2>1测试一下,不会报没有2文件的错误,但会输出一个空的文件1;
ls xxx 2>1测试,没有xxx这个文件的错误输出到了1中;
ls xxx 2>&1测试,不会生成1这个文件了,不过错误跑到标准输出了;
ls xxx >out.txt 2>&1,实际上可换成ls xxx 1>out.txt 2>&1;重定向符号>默认是1,错误和输出都传到out.txt了
command > file 2>&1
首先是command > file将标准输出重定向到file中,2>&1是标准错误拷贝了标准输出的行为,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中。
command 2>&1 >file
2>&1标准错误拷贝了标准输出的行为,但此时标准输出还是在终端。>file后输出才被重定向到file,但标准错误仍然保持在终端
2表示错误输出
ls -al 2>/dev/null // /dev/null同黑洞一样,只是把东西扔掉而已