Unix / Linux - Shell 输入/输出重定向

  • 简述

    本章,我们将详细讨论 Shell 输入/输出重定向。大多数 Unix 系统命令从您的终端获取输入并将结果输出发送回您的终端。命令通常从标准输入读取其输入,默认情况下它恰好是您的终端。类似地,命令通常将其输出写入标准输出,默认情况下也是您的终端。
  • 输出重定向

    通常用于标准输出的命令的输出可以轻松地转移到文件中。此功能称为输出重定向。
    如果符号 > file 附加到任何通常将其输出写入标准输出的命令,则该命令的输出将写入文件而不是终端。
    检查以下内容 who command 重定向用户文件中命令的完整输出。
    
    $ who > users
    
    请注意,终端上没有出现任何输出。这是因为输出已从默认标准输出设备(终端)重定向到指定文件。您可以检查用户文件的完整内容 -
    
    $ cat users
    oko         tty01   Sep 12 07:30
    ai          tty15   Sep 12 13:32
    ruth        tty21   Sep 12 10:10
    pat         tty24   Sep 12 13:07
    steve       tty25   Sep 12 13:03
    $
    
    如果命令将其输出重定向到文件并且该文件已包含一些数据,则该数据将丢失。考虑以下示例 -
    
    $ echo line 1 > users
    $ cat users
    line 1
    $
    
    您可以使用 >> 运算符将输出附加到现有文件中,如下所示 -
    
    $ echo line 2 >> users
    $ cat users
    line 1
    line 2
    $
    
  • 输入重定向

    正如命令的输出可以重定向到文件一样,命令的输入也可以从文件重定向。作为greater-than character > 用于输出重定向, less-than character < 用于重定向命令的输入。
    通常从标准输入获取输入的命令可以以这种方式从文件重定向其输入。例如,要计算上面生成的文件用户中的行数,您可以执行如下命令 -
    
    $ wc -l users
    2 users
    $
    
    执行后,您将收到以下输出。您可以通过重定向标准输入来计算文件中的行数wc来自文件用户的命令-
    
    $ wc -l < users
    2
    $
    
    请注意,wc 命令的两种形式产生的输出存在差异。在第一种情况下,文件 users 的名称与行数一起列出;在第二种情况下,它不是。
    在第一种情况下, wc 知道它正在从文件 users 读取其输入。在第二种情况下,它只知道它正在从标准输入读取其输入,因此它不显示文件名。
  • 这里文档

    一种 here document 用于将输入重定向到交互式 shell 脚本或程序。
    通过为交互式程序或交互式 shell 脚本提供所需的输入,我们可以在没有用户操作的情况下在 shell 脚本中运行交互式程序。
    a的一般形式 here 文件是 -
    
    command << delimiter
    document
    delimiter
    
    这里 shell 解释了 <<运算符作为读取输入的指令,直到找到包含指定分隔符的行。然后,所有输入行直到包含分隔符的行都被送入命令的标准输入中。
    分隔符告诉 shell here文档已完成。没有它,shell 将永远读取输入。分隔符必须是不包含空格或制表符的单个单词。
    以下是命令的输入 wc -l 计算总行数 -
    
    $wc -l << EOF
       This is a simple lookup program 
        for good (and bad) restaurants
        in Cape Town.
    EOF
    3
    $
    
    您可以使用 here document 使用您的脚本打印多行,如下所示 -
    
    #!/bin/sh
    cat << EOF
    This is a simple lookup program 
    for good (and bad) restaurants
    in Cape Town.
    EOF 
    
    执行后,您将收到以下结果 -
    
    This is a simple lookup program
    for good (and bad) restaurants
    in Cape Town.
    
    以下脚本与 vi 文本编辑器并将输入保存在文件中 test.txt.
    
    #!/bin/sh
    filename=test.txt
    vi $filename <<EndOfCommands
    i
    This file was created automatically from
    a shell script
    ^[
    ZZ
    EndOfCommands
    
    如果您使用 vim 作为 vi 运行此脚本,那么您可能会看到如下输出 -
    
    $ sh test.sh
    Vim: Warning: Input is not from a terminal
    $
    
    运行脚本后,您应该看到以下内容添加到文件中 test.txt
    
    $ cat test.txt
    This file was created automatically from
    a shell script
    $
    
  • 丢弃输出

    有时您需要执行命令,但不希望输出显示在屏幕上。在这种情况下,您可以通过将输出重定向到文件来丢弃输出/dev/null
    
    $ command > /dev/null
    
    这里的 command 是您要执行的命令的名称。文件/dev/null 是一个特殊的文件,它会自动丢弃所有输入。
    要丢弃命令的输出及其错误输出,请使用标准重定向来重定向 STDERRSTDOUT
    
    $ command > /dev/null 2>&1
    
    这里 2 代表 STDERR1 代表 STDOUT. 您可以通过将 STDOUT 重定向到 STDERR 来显示消息到 STDERR,如下所示 -
    
    $ echo message 1>&2
    
  • 重定向命令

    以下是可用于重定向的完整命令列表 -
    序号 命令和描述
    1
    pgm > file
    pgm 的输出被重定向到文件
    2
    pgm < file
    程序 pgm 从文件中读取它的输入
    3
    pgm >> file
    pgm 的输出附加到文件
    4
    n > file
    带有描述符的流的输出 n 重定向到文件
    5
    n >> file
    带有描述符的流的输出 n 附加到文件
    6
    n >& m
    合并来自流的输出 n 与流 m
    7
    n <& m
    合并来自流的输入 n 与流 m
    8
    << tag
    标准输入从这里到行首的下一个标签
    9
    &verbar
    从一个程序或进程中获取输出,并将其发送到另一个程序或进程
    注意文件描述符 0 通常是标准输入(STDIN), 1 是标准输出 (STDOUT),并且 2 是标准错误输出 (STDERR)。