Chinaunix首页 | 论坛 | 博客
  • 博客访问: 372728
  • 博文数量: 84
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 940
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-12 20:30
文章分类

全部博文(84)

文章存档

2010年(18)

2009年(27)

2008年(39)

我的朋友

分类:

2008-10-22 23:20:01

      标准输入、输出和错误

     当我们在 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) |
给主人留下些什么吧!~~