管道和文件重定向的区别 - BASH

时间:2015-11-04 20:50:21

标签: bash shell redirect

重定向用于重定向stdout / stdin / stderr! 例如:ls > log.txt.

管道用于将命令的输出作为另一个命令的输入。 例如:ls | grep file.txt

为什么这两个运营商正在做同样的事情?

为什么不写ls > grep来传递输出,这不仅仅是一种重定向吗?

我意识到Linux是“做一件事,做得好”,所以我必须有更多合理的理由让我失踪。

3 个答案:

答案 0 :(得分:4)

需要区分语法功能 - 使用>|会很好。

如果您在两个场景中使用了>,您将如何知道

ls > grep

正在尝试写入名为grep文件或将输入发送到grep 命令

grep可能不是最好的例子,因为你可能会因grep的强制性论点而出现歧义;但是,(可选)确实存在无参数命令,例如column that other guy在评论中提供了另一个示例:test可以引用测试输出文件,也可以引用standard test command的无参数调用。

另一种看待它的方式:

您的建议主要是使用>作为通用的send-output-somewhere运算符,而不管目标的类型(文件与命令)。

但是,只有转移需要消除歧义,然后你必须在指定目标时消除歧义 - 它是要输出的文件还是要运行的命令?

鉴于shell在简单命令的第一个标记时也具有隐式消除歧义功能 - foo [...]只调用命令 - 区分操作员级别 - >输出到文件,|用于发送命令 - 是明智的选择。

答案 1 :(得分:1)

他们没有做同样的工作。如果你采取这个例子:

ls > grep

这是获取ls的输出并将其写入名为grep。

的文件

现在,如果您要做类似的事情:

ls | grep '.*.txt'

这将获取任何txt文件的ls和grep输出。它们绝不会提供相同的结果。

答案 2 :(得分:1)

这实际上会使>执行两个事情,打开文件或运行新程序,具体取决于操作数。 (当参数是可执行文件的名称时忽略歧义:我们是否覆盖它或运行它?)

bash和其他一些shell提供了额外的语法(进程替换),它在技术上取代了| need ,尽管不是你选择使用的方式它在管道上。例如,你可以写

ls > >(grep regex)

>(...)被视为文件的“名称”(实际上,您可以运行echo >(true)以查看该文件名是什么),其内容作为输入提供给随附的命令。现在,代替处理从A到B输入的输出的单个运算符|,您有一个运算符>来重定向输出,而另一个运算符来重定向输入。

它也是对称的:

grep regex < <(ls)
# or grep regex <(ls), since grep can read from standard input or a named file

<(...)是输入文件的“名称”,其内容来自随附命令的输出。

进程替换(及其基础,命名管道)的好处是当您希望一个进程写入多个进程时:

command1 | tee >(command2) >(command3) >(command4)

或从一个进程中读取许多进程:

diff <(command1) <(command2)