Unix 简明教程

Unix / Linux - Shell Input/Output Redirections

在本章中,我们将详细讨论 Shell 输入/输出重定向。大多数 Unix 系统命令从你的终端获取输入并将产生的输出发回你的终端。一个命令通常从标准输入读取其输入,而默认情况下你的终端就是标准输入。类似地,一个命令通常将它的输出写入到标准输出,而默认情况下你的终端也是标准输出。

Output Redirection

本来打算用作标准输出的命令输出可以轻松地改发到文件。这种功能称为输出重定向。

如果符号 > file 附加到任何通常将它的输出写入到标准输出的命令,那么该命令的输出将被写入到 file 而不是你的终端。

查看以下 who 命令,它将命令的完整输出重定向到 users 文件。

$ who > users

请注意,没有输出出现在终端上。这是因为输出已被从默认的标准输出设备(终端)重定向到了指定的文件中。你可以查看 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
$

Input Redirection

与将命令的输出重定向到文件一样,也可以将命令的输入重定向到文件。与 greater-than character > 用于输出重定向一样, less-than character < 用于重定向命令的输入。

通常从标准输入获取输入的命令可以以这种方式将它们的输入重定向到一个文件中。例如,要计算上面由用户生成的文本文件中的行数,您可以执行如下命令:

$ wc -l users
2 users
$

执行后,您将收到以下输出。您可以通过将 wc 命令的标准输入从文件用户重定向来计算文件中行的数量:

$ wc -l < users
2
$

请注意,wc 命令产生的两种形式的输出存在差异。在第一种情况下,文件 users 的名称用引号与行数列在一起;在第二种情况下,则没有。

在第一种情况下,wc 知道它正在从文件 users 读取输入。在第二种情况下,它只知道它正在从标准输入读取输入,因此它不显示文件名称。

Here Document

here document 用于将输入重定向到交互式 shell 脚本或程序。

我们可以在 shell 脚本中运行一个交互式程序,而无需用户操作,方法是为交互式程序或交互式 shell 脚本提供所需的输入。

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
$

Discard the output

有时您需要执行命令,但是您不想在屏幕上显示输出。在这种情况下,您可以通过将输出重定向到文件 /dev/null 来丢弃输出:

$ command > /dev/null

这里 command 是您要执行的命令的名称。文件 /dev/null 是一个特殊文件,自动丢弃其所有输入。

要丢弃命令的输出及其错误输出,请使用标准重定向将 STDERR 重定向到 STDOUT

$ command > /dev/null 2>&1

此处 2 表示 STDERR ,而 1 表示 STDOUT 。您可以将消息重定向到 STDERR,方法是将 STDOUT 重定向到 STDERR,如下所示 −

$ echo message 1>&2

Redirection Commands

以下是可用于重定向的命令的完整列表 −

Sr.No.

Command & Description

1

pgm &gt; file 程序的输出重定向到文件

2

pgm &lt; file 程序 pgm 从文件读取其输入

3

pgm &gt;&gt; file 程序的输出附加到文件

4

n &gt; file 从描述符为 n 的流输出重定向到文件

5

n &gt;&gt; file 从描述符为 n 的流输出附加到文件

6

n &gt;&amp; m 将从流 n 中输出合并到流 m

7

n &lt;&amp; m 将从流 n 中输入合并到流 m

8

&lt;&lt; tag 标准输入从此处通过行首的下一个标记获得

9

*

请注意,文件描述符 0 通常是标准输入 (STDIN), 1 是标准输出 (STDOUT),而 2 是标准错误输出 (STDERR)。