Linux中流的重定向简介
1. 简介
每当我们在 Linux 命令行上工作时,我们经常需要将数据从一个命令传递到另一个命令,比如将find 结果列表输入grep 。这就是流发挥作用的地方。
在本教程中,我们将了解什么是流以及我们如何使用它们。
2. 什么是流?
我们可以将最简单形式的流视为将数据(尤其是字符数据)从一个点传输到另一个点的管道。
输入流的一些示例是键盘、存储在文件中的文本数据和来自 I/O 设备的输入。我们可以将输出传送到文件、命令、窗口和其他 I/O 设备。
3. 样本数据
让我们创建一些示例文件以在后续部分中使用:
$ echo -e "tables\nladders\nchairs" > streamdata1
$ echo -e "planes\ntrains\nautomobiles" > streamdata2
我们已经创建了streamdata1和streamdata2文件并用一些数据填充它们:
$ cat streamdata1
tables
ladders
chairs
$ cat streamdata2
planes
trains
automobiles
4. 重定向输入
我们要查看的第一个流是STDIN。
**STDIN 指的是标准输入流;**通常,从键盘输入。STDIN 的文件句柄为 0(零)。
** <运算符用于将输入从文件或 I/O 设备数据传递到命令。 假设我们想要计算文件中的行数而不将文件名作为参数传递给wc 命令。我们可以通过重定向 STDIN 来做到这一点:
$ wc -l < streamdata1
5.重定向输出
接下来,让我们看一下**STDOUT,标准输出流。**此流的所有输出通常会发送到我们的终端窗口。STDOUT 的文件句柄是 1。
** >运算符用于将命令的输出定向到源;通常是一个文件。默认情况下,单个*>*将:
- 如果不存在则创建一个新文件
- 如果文件已经存在,则覆盖文件中任何预先存在的数据
让我们看看如何使用*cat * 命令发出streamdata1的内容并将输出发送到新文件:
$ cat streamdata1 > combinedstreamdata
当我们打印combinestreamdata文件的内容时,它看起来应该与streamdata1完全一样:
$ cat combinedstreamdata
tables
ladders
chairs
6.附加到现有文件
>覆盖数据时, »运算符通过附加到现有文件来保留数据。
让我们看看如何将streamdata2的内容添加到combinedstreamdata文件:
$ cat streamdata2 >> combinedstreamdata
combinedstreamdata文件现在包含我们的streamdata1和streamdata2文件的内容:
$ cat combinedstreamdata
tables
ladders
chairs
planes
trains
automobiles
7. 管道输出到输入
使用 Linux 命令时,将多个任务链接在一起是一个常见的用例。
随着 | (管道)运算符,我们可以通过将一个命令的输出作为输入传递给下一个命令,将许多命令链接在一起。
让我们尝试使用*|* 运算符将cat命令的输出流式传输到wc命令的输入流:
$ cat streamdata2 | wc -l
8.重定向错误
现在我们已经了解了流重定向的基础知识,让我们看看如何处理多个输出文件。
让我们尝试执行一个不存在的脚本并将其假想输出通过管道传输到日志文件:
$ exec doesnotexist.sh > out.log
我们收到此错误消息:
exec: doesnotexist.sh: not found
让我们看一下我们的命令写入out.log的内容:
$ cat out.log
**嗯,我们的日志文件是空的。**但是,我们确实看到了一条错误消息——我们可能也想记录它。
让我们看看如何重定向 STDOUT 和 STDERR 以捕获输出和错误输出:
$ exec doesnotexist.sh >out.log 2>err.log
在上面的语句中,我们将标准输出定向到 out.log并将标准错误定向到 err.log。
更具体地说,我们使用其文件句柄引用标准错误流 – 2>err.log 。我们不必为标准输出指定文件句柄,因为它的文件句柄是默认的。
让我们检查一下命令写入err.log的内容:
$ cat err.log
exec: doesnotexist.sh: not found
我们的错误消息已成功重定向到我们的错误日志文件。
在此示例中,我们处理了两个输出流(STDOUT、STDERR)并将每个输出流定向到其自己的日志文件。
9. 合并输出和错误
虽然我们可以将 STDOUT 和 STDERR 定向到它们自己的日志文件,但我们通常更喜欢处理单个日志文件的简单性。
** >& 运算符是一种特殊运算符,用于将输出从一个流定向到另一个流**。我们可以使用它将STDERR的输出通过管道传输到STDOUT:
让我们看看如何利用文件句柄和 >& 为我们提供一个包含 STDOUT 和 STDERR 输出的日志文件:
$ cat streamdata1 streamdata2 streamdata3 2>&1>out.log
$ cat out.log
tables
ladders
chairs
planes
trains
automobiles
cat: streamdata3: No such file or directory
正如预期的那样,在out.log中可以找到streamdata1和streamdata2的内容以及预期的错误消息,因为streamdata3实际上并不存在。