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

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


输出重定向

通常用于标准输出的命令的输出可以很容易地转移到文件中。 此功能称为输出重定向。

如果符号 > file 附加到任何通常将其输出写入标准输出的命令,该命令的输出将写入文件而不是您的终端。

检查以下 who 命令,该命令重定向用户文件中命令的完整输出。

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

输入重定向

正如命令的输出可以重定向到文件一样,命令的输入也可以从文件重定向。 由于 大于字符 > 用于输出重定向,小于字符 < 用于重定向命令的输入。

通常从标准输入获取输入的命令可以通过这种方式从文件中重定向输入。 比如统计上面生成的users文件的行数,可以执行如下命令 −

$ wc -l users
2 users
$

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

$ wc -l < users
2
$

请注意,wc 命令的两种形式产生的输出是不同的。 在第一种情况下,文件用户的名称与行数一起列出; 在第二种情况下,它不是。

在第一种情况下,wc 知道它正在从文件用户读取它的输入。 在第二种情况下,它只知道它正在从标准输入读取输入,所以它不显示文件名。


Here 文档

here 文档用于将输入重定向到交互式 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 文档使用您的脚本打印多行,如下所示 −

#!/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 是一个特殊文件,它会自动丢弃所有输入。

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

$ 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

|

从一个程序或进程获取输出,并将其发送到另一个

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