20. I/O 重定向

目录

有三个默认打开的文件[1], stdin(标准输入,键盘),stdout(标准输出, 屏幕)和 stderr(标准错误,屏幕上输出的错误信息)。这些和任何其他打开的文件都可以被重定向。重定向仅仅意味着捕获输出文件,命令,脚本,甚至是一个脚本的代码块(样例 3-1)和(样例 3-2) 作为另一个文件,命令,程序或脚本的输入。

每个打开的文件都有特定的文件描述符。[2],而 stdinstdoutstderr 的文件描述符分别为 0,1,2。当然了,还有附件的文件描述符 3 - 9。有时候为stdinstdoutstderr临时性的复制链接分配这些附加的文件描述符会非常有用.[3]。这简化了复杂重定向和重组后的恢复(见样例 20-1)

   COMMAND_OUTPUT >
      # 重定向标准输出到一个文件.
      # 如果文件不存在则创建,否则覆盖.

      ls -lR > dir-tree.list
      # 创建了一个包含目录树列表的文件.

   : > filename
      # ">" 清空了文件.
      # 如果文件不存在,则创建了个空文件 (效果类似 'touch').
      # ":" 是个虚拟占位符, 不会有输出.

   > filename    
      # ">" 清空了文件.
      # 如果文件不存在,则创建了个空文件 (效果类似 'touch').
      # (结果和上述的 ": >" 一样, 但在某些 shell 环境中不能正常运行.)

   COMMAND_OUTPUT >>
      # 重定向标准输出到一个文件.
      # 如果文件不存在则创建,否则新内容在文件末尾追加.


      # 单行重定向命令 (只作用于本身所在的那行):
      # --------------------------------------------------------------------

   1>filename
      # 以覆盖的方式将 标准错误 重定向到文件 "filename."
   1>>filename
      # 以追加的方式将 标准输出 重定向到文件 "filename."
   2>filename
      # 以覆盖的方式将 标准错误 重定向到文件 "filename."
   2>>filename
      # 以追加的方式将 标准错误 重定向到文件 "filename."
   &>filename
      # 以覆盖的方式将 标准错误 和 标准输出 同时重定向到文件 "filename."
      # 在 bash 4 中才有这个新功能.

   M>N
     # "M" 是个文件描述符, 如果不明确指定,默认为 1.
     # "N" 是个文件名.
     # 文件描述符 "M" 重定向到文件 "N."
   M>&N
     # "M" 是个文件描述符, 如果不设置默认为 1.
     # "N" 是另一个文件描述符.

      #==============================================================================

      # 重定向 标准输出,一次一行.
      LOGFILE=script.log

      echo "This statement is sent to the log file, \"$LOGFILE\"." 1>$LOGFILE
      echo "This statement is appended to \"$LOGFILE\"." 1>>$LOGFILE
      echo "This statement is also appended to \"$LOGFILE\"." 1>>$LOGFILE
      echo "This statement is echoed to stdout, and will not appear in \"$LOGFILE\"."
      # 这些重定向命令在每行结束后自动"重置".



      # 重定向 标准错误,一次一行.
      ERRORFILE=script.errors

      bad_command1 2>$ERRORFILE       #  Error message sent to $ERRORFILE.
      bad_command2 2>>$ERRORFILE      #  Error message appended to $ERRORFILE.
      bad_command3                    #  Error message echoed to stderr,
                                      #+ and does not appear in $ERRORFILE.
      # 这些重定向命令每行结束后会自动“重置”.
	#=======================================================================

可以用单个命令行表示输入和输出的多个重定向或管道.

更多详情见样例 16-31 and 样例 A-14.

多个输出流可以重定向到一个文件.

关闭文件描述符

子进程能继承文件描述符.这就是管道符能工作的原因.通过关闭文件描述符来防止继承 .

更多关于 I/O 重定向详情见 Appendix F.

注意

[1] 在 UNIX 和 Linux 中, 数据流和周边外设(device files) 都被看做文件.

[2] 文件描述符 仅仅是操作系统分配的一个可追踪的打开的文件号. 可以认为是一个简化的文件指针. 类似于 C 语言的 文件句柄.

[3] 当 bash 创建一个子进程的时候使用 文件描述符 5 会有问题. 例如 exec, 子进程继承了文件描述符 5 (详情见 Chet Ramey's 归档的 e-mail, SUBJECT: RE: File descriptor 5 is held open). 最好将这个文件描述符单独规避.

最后更新于

这有帮助吗?