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
正如预期的那样,streamdata1和streamdata2的内容在out.log中被发现,同时还有预期的错误信息,因为streamdata3事实上并不存在。
10.结语
在本教程中,我们研究了什么是Linux流,并看到了如何使用它们。
我们通过几个场景,展示了流重定向的不同能力。