我是 Linux 系统的新手,我真的不明白为什么我们需要两个可以重定向输出的运算符:管道|
和输出重定向运算符>
?我们不能总是使用第二个吗?大多数情况下,我看到如果将多个命令链接在一起,则使用管道。但是,如果输出重定向到文件,如echo 'hello' > filename
,则使用输出重定向运算符。我在这里遗漏了什么?
答案1
我相信 < > 运算符用于读取/写入文件,而 | 符号用于将一个命令的标准输出传输到另一个命令。
cal | less
让您可以使用 less 命令查看 cal 的输出。
cal > less
将 cal 的输出放入名为 less 的文件中。
答案2
|
用于将一个命令的输出作为输入发送到管道符号后面的另一个命令。$ echo foo | grep -o 'f' f
要将一个命令的输出重定向到文件,您可以使用输出重定向
>
运算符。$ echo foo > file1
它写入
foo
file1。您无需手动创建该文件。如果您想将输出重定向到多个文件,那么您必须使用
tee
命令。echo foo | tee file1 file2
它写入
foo
文件 1 和文件 2。您无需手动创建该文件。现在文件 1 和文件 2 仅包含字符串foo
。
答案3
关于输出重定向有很多讨论,但我认为这个问题是关于输入的。我将忽略>
和,>>
因为它们与输入无关。相反,我将重点关注<
、<(...)
和|
:
<
需要从文件中读取STDIN
数据,<(...)
STDOUT
为命令提供文件句柄(...
此处)|
STDOUT
从一个进程到下STDIN
一个进程的管道
因此,<
并不直接等同于管道(它从文件中读取数据), 并且<(...)
正在从正确位置读取数据,但它会将文件句柄作为输出。您需要将它们组合起来,才能提供与管道等同的功能。
a | b
< <(a) b
读到这里,我希望它能完整解释管道存在的原因。这样可读性更强。
答案4
要记住的关键点是,管道是进程间通信设备,允许两个进程(命令的真正含义就是)交换数据,而重定向操作符用于操纵特定进程的写入位置。
在视频中Unix 管道语言的创造者awk
,也是 AT&T Unix 的原始参与者之一 Brian Kernighan 解释说:
首先,你不必编写一个庞大的程序 - 你已经有了现有的小型程序,它们可能已经完成了部分工作……另一个是,如果你将数据存储在文件中,你处理的数据量可能不适合……因为记住,我们回到了那个时代,如果你幸运的话,这些东西上的磁盘有 1 到 2 兆字节的数据……所以管道永远不必实例化整个输出
如您所见,在创建管道的背景下,它们实际上不仅仅是通信设备,还可以节省存储空间并简化开发。当然,我们可以对所有内容使用输出/输入重定向(尤其是在存储容量达到 TB 级的今天),但是从存储的角度来看,这样做效率低下,处理速度也低下 - 请记住,您是使用直接将一个命令的输出馈送到另一个命令|
。考虑类似的事情command1 | grep 'something'
。如果您先将输出写入command1
文件,则写入所有内容需要时间,然后再浏览grep
整个文件。通过管道和输出缓冲的事实(意味着左侧进程在右侧进程准备再次读取之前暂停),输出直接从一个命令传到另一个命令,从而节省时间。
值得注意的是,对于进程间通信,有一个用例命名管道,您可以使用>
运算符从一个命令写入,并<
让另一个命令从中读取,这是一个用例,您确实希望在文件系统上有特定的目标,多个脚本/命令可以写入并同意该特定目标。但是当没有必要时,匿名管道|
就是您真正需要的。