Unix 简明教程

Unix / Linux - Shell Input/Output Redirections

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

In this chapter, we will discuss in detail about the Shell input/output redirections. Most Unix system commands take input from your terminal and send the resulting output back to your terminal. A command normally reads its input from the standard input, which happens to be your terminal by default. Similarly, a command normally writes its output to standard output, which is again your terminal by default.

Output Redirection

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

The output from a command normally intended for standard output can be easily diverted to a file instead. This capability is known as output redirection.

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

If the notation > file is appended to any command that normally writes its output to standard output, the output of that command will be written to file instead of your terminal.

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

Check the following who command which redirects the complete output of the command in the users file.

$ who > users

请注意,没有输出出现在终端上。这是因为输出已被从默认的标准输出设备(终端)重定向到了指定的文件中。你可以查看 users 文件以获得完整内容 −

Notice that no output appears at the terminal. This is because the output has been redirected from the default standard output device (the terminal) into the specified file. You can check the users file for the complete content −

$ 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
$

如果一个命令的输出被重定向到一个文件且该文件已经包含了一些数据,那么那些数据将被丢失。考虑以下示例 −

If a command has its output redirected to a file and the file already contains some data, that data will be lost. Consider the following example −

$ echo line 1 > users
$ cat users
line 1
$

您可以使用 >> 运算符将输出附加到现有文件中,如下所示:

You can use >> operator to append the output in an existing file as follows −

$ echo line 2 >> users
$ cat users
line 1
line 2
$

Input Redirection

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

Just as the output of a command can be redirected to a file, so can the input of a command be redirected from a file. As the greater-than character > is used for output redirection, the less-than character < is used to redirect the input of a command.

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

The commands that normally take their input from the standard input can have their input redirected from a file in this manner. For example, to count the number of lines in the file users generated above, you can execute the command as follows −

$ wc -l users
2 users
$

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

Upon execution, you will receive the following output. You can count the number of lines in the file by redirecting the standard input of the wc command from the file users −

$ wc -l < users
2
$

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

Note that there is a difference in the output produced by the two forms of the wc command. In the first case, the name of the file users is listed with the line count; in the second case, it is not.

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

In the first case, wc knows that it is reading its input from the file users. In the second case, it only knows that it is reading its input from standard input so it does not display file name.

Here Document

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

A here document is used to redirect input into an interactive shell script or program.

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

We can run an interactive program within a shell script without user action by supplying the required input for the interactive program, or interactive shell script.

here 文档的一般形式是:

The general form for a here document is −

command << delimiter
document
delimiter

这里 shell 将 << 运算符解释为一个指令,指在它找到包含指定分界符的行之前,读取输入。然后将包含分界符的行之前的全部输入行送入命令的标准输入。

Here the shell interprets the << operator as an instruction to read input until it finds a line containing the specified delimiter. All the input lines up to the line containing the delimiter are then fed into the standard input of the command.

分界符告诉 shell, here 文档已完成。如果没有分界符,shell 将继续永远读取输入。分界符必须是不包含空格或选项卡的单个单词。

The delimiter tells the shell that the here document has completed. Without it, the shell continues to read the input forever. The delimiter must be a single word that does not contain spaces or tabs.

以下是对命令 wc -l 的输入,用于计算总行数:

Following is the input to the command wc -l to count the total number of lines −

$wc -l << EOF
   This is a simple lookup program
	for good (and bad) restaurants
	in Cape Town.
EOF
3
$

您可以使用 here document 来使用您的脚本打印多行,如下所示:

You can use the here document to print multiple lines using your script as follows −

#!/bin/sh

cat << EOF
This is a simple lookup program
for good (and bad) restaurants
in Cape Town.
EOF

执行后,您会收到以下结果 −

Upon execution, you will receive the following result −

This is a simple lookup program
for good (and bad) restaurants
in Cape Town.

以下脚本运行了文本编辑器 vi 的一个会话,并将输入保存在文件 test.txt 中。

The following script runs a session with the vi text editor and saves the input in the file test.txt.

#!/bin/sh

filename=test.txt
vi $filename <<EndOfCommands
i
This file was created automatically from
a shell script
^[
ZZ
EndOfCommands

如果您使用 vim 作为 vi 运行此脚本,那么您可能会看到如下的输出:

If you run this script with vim acting as vi, then you will likely see output like the following −

$ sh test.sh
Vim: Warning: Input is not from a terminal
$

运行脚本后,您应该看到以下内容被添加到文件 test.txt 中:

After running the script, you should see the following added to the file test.txt

$ cat test.txt
This file was created automatically from
a shell script
$

Discard the output

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

Sometimes you will need to execute a command, but you don’t want the output displayed on the screen. In such cases, you can discard the output by redirecting it to the file /dev/null

$ command > /dev/null

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

Here command is the name of the command you want to execute. The file /dev/null is a special file that automatically discards all its input.

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

To discard both output of a command and its error output, use standard redirection to redirect STDERR to STDOUT

$ command > /dev/null 2>&1

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

Here 2 represents STDERR and 1 represents STDOUT. You can display a message on to STDERR by redirecting STDOUT into STDERR as follows −

$ echo message 1>&2

Redirection Commands

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

Following is a complete list of commands which you can use for redirection −

Sr.No.

Command & Description

1

pgm > file Output of pgm is redirected to file

2

pgm < file Program pgm reads its input from file

3

pgm >> file Output of pgm is appended to file

4

n > file Output from stream with descriptor n redirected to file

5

n >> file Output from stream with descriptor n appended to file

6

n >& m Merges output from stream n with stream m

7

n <& m Merges input from stream n with stream m

8

<< tag Standard input comes from here through next tag at the start of line

9

*

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

Note that the file descriptor 0 is normally standard input (STDIN), 1 is standard output (STDOUT), and 2 is standard error output (STDERR).