在本章中,我们将详细讨论Shell输入/输出重定向。大多数Unix系统命令从您的终端获取输入,并将结果输出发送回您的终端。命令通常从标准输入中读取其输入,默认情况下它就是您的终端。同样,命令通常将其输出写到标准输出,默认情况下,这也是您的终端。
输出重定向
通常用于标准输出的命令的输出可以轻松地转移到文件中。此功能称为输出重定向。
如果将符号> file附加到通常将其输出写入标准输出的任何命令中,该命令的输出将被写入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
$
输入重定向
就像命令的输出可以重定向到文件一样,命令的输入也可以从文件重定向。由于大于字符>用于输出重定向,小于字符<用于重定向命令的输入。
通常可以从标准输入中获取输入的命令可以通过这种方式从文件中重定向其输入。例如,要计算上面生成的文件用户中的行数,可以执行以下命令-
$ wc -l users
2 users
$
执行后,您将收到以下输出。您可以通过从文件用户重定向wc命令的标准输入来计算文件中的行数–
$ wc -l < users
2
$
注意,两种形式的wc命令产生的输出有所不同。在第一种情况下,文件用户的名称与行数一起列出;在第二种情况下则不是。
在第一种情况下,wc知道它正在从文件用户读取其输入。在第二种情况下,它仅知道它正在从标准输入中读取其输入,因此它不显示文件名。
Here 文档
一个here文档用于输入重定向到一个交互的shell脚本或程序。
通过为交互式程序或交互式Shell脚本提供所需的输入,我们可以在Shell脚本中运行交互式程序而无需用户干预。
here文档的一般形式是-
command << delimiter
document
delimiter
在这里Shell将<<操作符解释为读取输入的指令,直到找到包含指定定界符的行。然后直到包含定界符的行的所有输入行都被馈送到命令的标准输入中。
定界符告诉Shellhere 文档已完成。没有它,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
命令是您要执行的命令的名称。文件/dev/null是一个特殊文件,该文件会自动丢弃其所有输入。
要放弃一个命令的输出和它的错误输出,使用标准重定向到重定向STDERR到STDOUT –
$ command > /dev/null 2>&1
这里2代表STDERR,1代表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)。