【发布时间】:2018-01-25 15:49:55
【问题描述】:
This question 帮助我理解了重定向和管道之间的区别,但示例侧重于重定向 STDOUT (echo foo > bar.txt) 和管道 STDIN (ls | grep foo)。
在我看来,任何可以写成my_command < file.txt 的命令也可以写成cat file.txt | my_command。什么情况下需要 STDIN 重定向?
除了使用cat 会产生一个额外的进程并且效率低于重定向STDIN 的事实之外,是否存在您必须使用STDIN 重定向的情况?换句话说,有没有理由将cat 的输出通过管道传输到另一个命令?
【问题讨论】:
-
重定向标准输入肯定是首选管道版本,因为它不会产生不必要的过程。一个更好的问题是何时需要 pipe。
-
@chepner - 当 command 正在生成
my_command在 STDIN 上读取的数据时,管道肯定是必要的。而且我可以看到如何将文件重定向到 STDIN(或者它是“将 STDIN 重定向到文件”?)更有效。我想知道的是,是否存在不能简单地将文件通过管道传输到 STDIN,而必须使用 STDIN 重定向方法的情况。我怎样才能更好地在我的问题中表达这一点? -
重定向从来不是必要的,但您的问题暗示您认为管道更好,应尽可能避免重定向。恰恰相反:您应该尽可能使用重定向,并且只在必要时使用管道。当 shell 完全能够自行打开文件时,管道使用
cat打开文件进行读取。 -
如果您的程序尝试
seek()或多次读取其输入文件的一部分,它不能使用管道。这意味着,例如,可以通过启动处理不同输入文件块的多个进程来并行化的sort版本在从cat读取时根本无法提供该功能(至少没有从首先将 FIFO 放入一个临时文件中,而不仅仅是能够让每个线程/子进程 seek() 直接访问不同的输入片段)。 -
考虑
wc -c作为另一个例子——给定一个真实文件的句柄,它可以使用stat()-family调用来获取文件在恒定时间内的长度,无论需要多长时间。给定一个管道,它必须将整个内容读取到最后并计算字节数,因此我们不仅在谈论 FIFO 开销,而且还必须使用完全不同的算法开销。
标签: linux bash redirect pipe stdin