Linux中的流重定向指南

评论 0 浏览 0 2019-10-26

1.绪论

每当我们在Linux命令行上工作时,我们经常要把数据从一个命令传递到另一个命令,比如把find的结果列表输入到grep。这就是流开始发挥作用的地方。

在本教程中,我们将看看什么是流,以及我们如何与它们一起工作。

2.什么是流?

我们可以把流的最简单形式看作是一个管道,它将数据–特别是字符数据–从一个点传送到另一个点。

输入流的一些例子是键盘、存储在文件中的文本数据和I/O设备的输入。我们可以将输出交付给文件、命令、窗口和其他I/O设备。

3.样本数据

让我们创建一些样本文件,以便在随后的章节中使用。

$ echo -e "tables\nladders\nchairs" > streamdata1
$ echo -e "planes\ntrains\nautomobiles" > streamdata2

我们已经创建了streamdata1streamdata2文件,并将一些数据填充到它们中。

$ 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文件包含了我们的streamdata1streamdata2文件的内容。

$ 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

正如预期的那样,streamdata1streamdata2的内容在out.log中被发现,同时还有预期的错误信息,因为streamdata3事实上并不存在。

10.结语

在本教程中,我们研究了什么是Linux流,并看到了如何使用它们。

我们通过几个场景,展示了流重定向的不同能力。

最后更新2022-12-06
0 个评论
标签