为什么使用管道而不是输入重定向

为什么使用管道而不是输入重定向

我是 Linux 系统的新手,我真的不明白为什么我们需要两个可以重定向输出的运算符:管道|和输出重定向运算符>?我们不能总是使用第二个吗?大多数情况下,我看到如果将多个命令链接在一起,则使用管道。但是,如果输出重定向到文件,如echo 'hello' > filename,则使用输出重定向运算符。我在这里遗漏了什么?

答案1

我相信 < > 运算符用于读取/写入文件,而 | 符号用于将一个命令的标准输出传输到另一个命令。

cal | less 

让您可以使用 less 命令查看 cal 的输出。

cal > less

将 cal 的输出放入名为 less 的文件中。

答案2

  • |用于将一个命令的输出作为输入发送到管道符号后面的另一个命令。

    $ echo foo | grep -o 'f'
    f
    
  • 要将一个命令的输出重定向到文件,您可以使用输出重定向>运算符。

    $ echo foo > file1
    

    它写入foofile1。您无需手动创建该文件。

  • 如果您想将输出重定向到多个文件,那么您必须使用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整个文件。通过管道和输出缓冲的事实(意味着左侧进程在右侧进程准备再次读取之前暂停),输出直接从一个命令传到另一个命令,从而节省时间。

值得注意的是,对于进程间通信,有一个用例命名管道,您可以使用>运算符从一个命令写入,并<让另一个命令从中读取,这是一个用例,您确实希望在文件系统上有特定的目标,多个脚本/命令可以写入并同意该特定目标。但是当没有必要时,匿名管道|就是您真正需要的。

相关内容