8.2.3 重定向标准错误输出
第5章介绍了标准输出的概念,并解释了如何重定向命令的标准输出。除了标准输出之外,命令还可以将输出发送到标准错误输出。命令将错误消息发送到标准错误输出,这样就可以避免与发送到标准输出的信息混淆在一起。
与处理标准输出一样,默认情况下,shell将命令的标准错误输出发送到屏幕上。除非重定向标准输出和标准错误输出中的某一个,否则不能区分命令的输出到底是标准输出还是标准错误输出。本节讲述Bourne Again Shell使用的语法。如果使用TC Shell,请参见第9.3.4节。
文件描述符 文件描述符是程序发送输出和获取输入的地方。当执行一个程序时,运行该程序的进程打开了3个文件描述符,分别是:0(标准输入)、1(标准输出)和2(标准错误输出)。重定向输出符号(>)是1>的简写,它通知shell重定向标准输出。类似地,<是0<的简写,表示重定向标准输入。符号2>将重定向标准错误输出。参见第11.2节以获取更多信息。
下面的示例演示了如何将标准输出和标准错误输出重定向到不同的文件和相同的文件。当运行cat实用程序时,如果所带参数中的某个文件不存在,而另一个文件存在,那么cat将发送一条错误消息到标准错误输出,同时还将已存在的那个文件复制一份到标准输出。除非重定向,否则两条消息都将出现在屏幕上。
$ cat y $ cat x y |
将命令的标准输出重定向时,发送到标准错误输出的输出将不受影响,仍然出现在屏幕上。
$ cat x y > hold |
类似地,当使用管道发送标准输出时,标准错误输出也不会受到影响。下面的示例将cat的标准输出通过管道发送给tr(在本例中,这个程序将小写字母转换为大写字母)。cat发送到标准错误输出的文本并没有转换,这是因为它直接发送到屏幕,并没有经过这个管道。
$ cat x y | tr "[a-z]" "[A-Z]" |
下面的示例将标准输出和标准错误输出重定向到不同的文件中。符号2>告诉shell将标准错误输出(文件描述符为2)重定向到的具体位置。1>告诉shell将标准输出(文件描述符为1)重定向到的具体位置。可以使用>代替1>。
$ cat x y 1> holdl 2> ho1d2 |
复制文件描述符 在下一个示例中,1>将标准输出重定向到文件hold。然后,2>&1声明文件描述符2为文件描述符1的副本。这样做的结果是,标准输出和标准错误输出均被重定向到文件hold中。
$ cat x y 1> hold 2>&1 |
在这个示例中,1>hold放在了2>&1的前面。如果将它们的顺序颠倒的话,在标准输出重定向到文件hold之前,标准错误输出就已经复制了标准输出的一个副本。这样一来,就只有标准输出被重定向到文件hold。
在下面的示例中,文件描述符2是文件描述符1的副本,通过一个到tr命令的管道将输出发送到文件描述符1。
$ cat x y 2>&1 | tr "[a-z]" "[A-Z]" |
发送错误到标准错误输出 还可以使用1>&2将命令的标准输出重定向到标准错误输出。shell脚本中经常使用这项技术将echo的输出发送到标准错误输出。在下面的脚本中,第1个echo命令的标准输出被重定向到标准错误输出:
$ cat message_demo |
如果重定向message_demo的标准输出,那么像第1条echo命令产生的那些错误消息将打印到屏幕,这是因为还没有重定向标准错误输出。因为shell脚本的标准输出经常被重定向到另一个文件,所以可以使用这项技术显示脚本产生的错误消息。lnks脚本就使用了这项技术。在脚本中,还可以使用内置命令exec创建另外的文件描述符,并重定向shell脚本的标准输入、标准输出和标准错误输出。
Bourne Again Shell所支持的重定向操作符如表8-2所示。
表8-2 重定向操作符
操 作 符 |
含 义 |
<filename |
将标准输入重定向为文件filename |
>filename |
除非文件filename已存在并且设置了noclobber标记,否则标准输出将被重定向到文件filename;如果文件filename不存在且没有设置noclobber标记,那么重定向操作将创建该文件 |
>|filename |
即使文件filename存在且设置了noclobber标记,仍将标准输出重定向到该文件 |
>>filename |
除非文件filename已存在并且设置了noclobber标记,否则标准输出将被重定向到文件filename,并将内容添加到原文件的末尾;如果没有设置noclobber标记,并且文件filename不存在,那么将创建该文件 |
<&m |
从文件描述符m复制标准输入 |
[n]>&m |
从文件描述符m |