标准输入、输出和错误
当我们在 s h e l l中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描
述符来引用这些文件。由于文件描述符不容易记忆, shell同时也给出了相应的文件名。
下面就是这些文件描述符及它们通常所对应的文件名:
文 件 文件描述符
输入文件 — 标准输入 0
输出文件 — 标准输出 1
错误输出文件 — 标准错误 2
系统中实际上有 12个文件描述符,但是正如我们在上表中所看到的, 0、1、2是标准输入、
输出和错误。可以任意使用文件描述符 3到9。
1 标准输入
标准输入是文件描述符0。它是命令的输入,缺省是键盘,也可以是文件或其他命令的输出。
2 标准输出
标准输出是文件描述符 1。它是命令的输出,缺省是屏幕,也可以是文件。
3 标准错误
标准错误是文件描述符 2。这是命令错误的输出,缺省是屏幕,同样也可以是文件。你可
能会问,为什么会有一个专门针对错误的特殊文件?这是由于很多人喜欢把错误单独保存到
一个文件中,特别是在处理大的数据文件时,可能会产生很多错误。
如果没有特别指定文件说明符,命令将使用缺省的文件说明符(你的屏幕,更确切地说
是你的终端) 。
文件重定向
在执行命令时,可以指定命令的标准输入、输出和错误,要实现这一点就需要使用文件
重定向。表 5-1列出了最常用的重定向组合,并给出了相应的文件描述符。
在对标准错误进行重定向时,必须要使用文件描述符,但是对于标准输入和输出来说,
这不是必需的。为了完整起见,我们在表 5-1中列出了两种方法。
表5-1 常用文件重定向命令
command > filename 把把标准输出重定向到一个新文件中
command >> filename 把标准输出重定向到一个文件中 (追加)
command 1 > fielname 把标准输出重定向到一个文件中
command > filename 2>&1 把标准输出和标准错误一起重定向到一个文件中
command 2 > filename 把标准错误重定向到一个文件中
command 2 >> filename 把标准输出重定向到一个文件中 (追加)
command >> filename 2>&1 把标准输出和标准错误一起重定向到一个文件中 (追加)
command < filename >filename2 把command命令以filename文件作为标准输入,
以filename2文件作为标准输出
command < filename 把command命令以filename文件作为标准输入
command << delimiter 把从标准输入中读入,直至遇到 delimiter分界符
command <&m 把文件描述符 m作为标准输入
command >&m 把标准输出重定向到文件描述符 m中
command <&- 把关闭标准输入
重定向标准输出
让我们来看一个标准输出的例子。在下面的命令中,把 /etc/passwd文件中的用户 I D域按
照用户命排列。该命令的输出重定向到 sort.out文件中。要提醒注意的是,在使用 sort命令的时
候(或其他含有相似输入文件参数的命令 ),重定向符号一定要离开 s o r t命令两个空格,否则该
命令会把它当作输入文件。
$ cat passwd | awk -F: '{print $1}' | sort 1>sort.out
从表5-1中可以看出,我们也可以使用如下的表达方式,结果和上面一样:
$ cat passwd | awk -F: '{print $1}' | sort >sort.out
可以把很多命令的输出追加到同一文件中。
$ls -l | grep ^d >>files.out
$ ls account* >>files.out
在上面的例子中,所有的目录名和以 account开头的文件名都被写入到 file.out文件中。
如果希望把标准输出重定向到文件中,可以用 > filename。在下面的例子中, ls命令的所
有输出都被重定向到 ls.out文件中:
$ ls >ls.out
如果希望追加到已有的文件中 (在该文件不存在的情况下创建该文件 ),那么可以使用
>>filename:
$ pwd >>path.out
$ find . -name "LPSO.doc" -print >> path.out
如果想创建一个长度为 0的空文件,可以用 '>filename':
$ >myfile
5.7.2 重定向标准输入
可以指定命令的标准输入。在 awk一章就会遇到这样的情况。下面给出一个这样的例子:
$ sort < name.txt
在上面的命令中, s o r t命令的输入是采用重定向的方式给出的,不过也可以直接把相应的
文件作为该命令的参数:
$ sort name.txt
在上面的例子中,还可以更进一步地通过重定向为 s o r t命令指定一个输出文件 n a m e . o u t。
这样屏幕上将不会出现任何信息 (除了错误信息以外 ):
$ sort name.out
在发送邮件时,可以用重定向的方法发送一个文件中的内容。在下面的例子中,用户
louise将收到一个邮件,其中含有文件 contents.txt中的内容:
$ mail louise < contents.txt
重定向操作符command << delimiter是一种非常有用的命令,通常都被称为“此处”文挡。
我们将在本书后面的章节深入讨论这一问题。现在只介绍它的功能。 shell将分界符delimiter之
后直至下一个同样的分界符之前的所有内容都作为输入,遇到下一个分界符, s h e l l就知道输
入结束了。这一命令对于自动或远程的例程非常有用。可以任意定义分界符 delimiter,最常见
的是EOF,而我最喜欢用 MAYDAY,这完全取决于个人的喜好。还可以在 <<后面输入变量。
下面给出一个例子,我们创建了一个名为 myfile的文件,并在其中使用了 TERM和LOGNAME
变量。
$ cat >> myfile << MAYDAY
>Hello there I am using a $TERM terminal
>and my user name is $LOGNAME
>bye...
>MAYDAY
$cat myfile
Hello there I am using a $TERM terminal
and my user name is $LOGNAME
bye...
重定向标准错误
为了重定向标准错误,可以指定文件描述符 2。让我们先来看一个例子,因为举例子往往
会让人更容易明白。在这个例子中, grep命令在文件 missiles中搜索trident字符串:
$grep "trident" missiles
grep:missiles: No such file or directory
g r e p命令没有找到该文件,缺省地向终端输出了一个错误信息。现在让我们把错误重定
向到文件/dev/null中(实际就上是系统的垃圾箱 ):
$ grep "trident" missiles 2>/dev/null
这样所有的错误输出都输送到了 /dev/null,不再出现在屏幕上。
如果你在对更重要的文件进行操作,可能会希望保存相应的错误。下面就是一个这样的
例子,这一次错误被保存到 grep.err文件中:
$ grep "trident" missiles 2>grep.err
$cat grep.err
grep;missiles: No such file or directory
还可以把错误追加到一个文件中。在使用一组命令完成同一个任务时,这种方法非常有
用。在下面的例子中,两个 g r e p命令把错误都输出到同一个文件中;由于我们使用了 > >符号
进行追加,后面一个命令的错误 (如果有的话 )不会覆盖前一个命令的错误。
$grep "LPSO" * 2 >>account.err
$grep "SILO" * 2 >>account.err
结合使用标准输出和标准错误
一个快速发现错误的方法就是,先将输出重定向到一个文件中,然后再把标准错误重定
向到另外一个文件中。下面给出一个例子:
我有两个审计文件,其中一个的确存在,而且包含一些信息,而另一个由于某种原因已
经不存在了 (但我不知道 )。我想把这两个文件合并到 accounts.out文件中。
$ cat account_qtr.doc account_end.doc 1>accounts.out 2>accounts.err
现在如果出现了错误,相应的错误将会保存在 accounts.err文件中。
$cat accounts.out
AVBD 34HJ OUT
AVFJ 31KO OUT
...
$cat accounts.err
cat:account_end.doc: No such file or directory
我事先并不知道是否存在 account_end.doc文件,使用上面的方法能够快速发现其中的错
误。
合并标准输出和标准错误
在合并标准输出和标准错误的时候,切记 s h e l l是从左至右分析相应的命令的。下面给出
一个例子:
$ cleanup >cleanup.out 2>&1
在上面的例子中,我们将 c l e a n u p脚本的输出重定向到 c l e a n u p . o u t文件中,而且其错误也
被重定向到相同的文件中。
$ grep "standard"* > grep.out 2>&1
在上面的例子中, g r e p命令的标准输出和标准错误都被重定向到 g r e p . o u t文件中。你在使
用前面提到的“此处”文挡时,有可能需要把所有的输出都保存到一个文件中,这样万一出
现了错误,就能够被记录下来。通过使用 2>&1就可以做到这一点,下面给出一个例子:
$cat >> filetest 2>&1 < >This is my home$HOME directory
>MAYDAY
$cat filetest
This is my home /home/dave directory
上面的例子演示了如何把所有的输出捕捉到一个文件中。在使用 c a t命令的时候,这可能
没什么用处,不过如果你使用“此处”文挡连接一个数据库管理系统
(例如使用 isql连接sybase )或使用f t p,这一点就变得非常重要了,因为这样就可以捕捉到所有的错误,以免这些
错误在屏幕上一闪而过,特别是在你不在的时候。
阅读(1839) | 评论(0) | 转发(0) |