重定向用于重定向stdout / stdin / stderr!
例如:ls > log.txt.
管道用于将命令的输出作为另一个命令的输入。
例如:ls | grep file.txt
为什么这两个运营商正在做同样的事情?
为什么不写ls > grep
来传递输出,这不仅仅是一种重定向吗?
我意识到Linux是“做一件事,做得好”,所以我必须有更多合理的理由让我失踪。
答案 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)