2015-11-04 78 views
2

重定向用于重定向stdout/stdin/stderr! 例:是用来给一个命令的输出作为输入到另一个命令ls > log.txt.管道和文件重定向的区别 - BASH

管道。 例如:ls | grep file.txt

为什么这两个操作员正在做同样的事情?

为什么不直接写ls > grep来通过输出,这不就是一种重定向吗?我认识到Linux是“做一件事,做得很好”的,所以我必须有更多的逻辑理由,我错过了。

+2

发送输出到文件vs发送输出作为输入到命令并非真的是一回事 – chiliNUT

+1

如果你想要一个名为'grep'的文件怎么办?现在你需要使用'./ grep'。 –

回答

4

需要差异化语法功能 - 并使用>|会做得很好。

如果您在使用>情况下,你怎么会知道

ls > grep 

是否试图写入文件命名为grep或输入发送到grep命令

grep也许不是最好的例子,因为您可能会试图通过存在grep的强制性参数来消除歧义;但是,(可选)不存在无自变量的命令,例如column
that other guy在评论中提供了另一个示例:test可能指的是测试输出文件或无参数调用standard testcommand


看它的另一种方式:

你的建议实质上是使用>作为一种通用的发送,输出的地方运营商,不论目标的类型(文件与指令)。

然而,只有转变需要消除歧义,然后可以选择指定目标时消除歧义 - 是一个文件输出到或命令来运行?

鉴于壳还具有隐含歧义功能,当它涉及到第一令牌一个简单的命令 - foo [...]永远只能调用命令 - 在操作者的水平区分 - >输出到文件,|发送到命令 - 是明智的选择。

+0

你仍然可以使用'ls>。/ grep' ...直到它也是一个程序;好的,我放弃了;) – Aaron

+0

@Aaron:用什么_specific_语法来区分命令和文件名是不相关的 - 关键是你需要消除歧义_,而'''和'|'确实提供了 - 并且这样做是为了几十年。 – mklement0

+1

一个很好的例子可能是'mycommand> test',它是一个测试文件的公平名称,也可能意味着运行命令'test'(这恰好没有参数就可以运行) –

1

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

ls > grep

这正在LS的输出,并将其写入文件名为grep的。现在

如果你做这样的事情:

ls | grep '.*.txt'

这将需要LS和grep的输出任何txt文件。他们决不会提供相同的结果。

+3

OP知道他们没有做同样的工作 - 他们的问题更多的是哲学/建筑性质:为什么不在这两种情况下使用_single construct_ - '>'? – mklement0

+0

啊,我明白你的意思了。 – ryekayo

+0

我认为这个答案确实解决了这个问题:''grep'在'| grep'创建一个文件。 grep'运行一个程序。这就是为什么同样的结构不能用于两者。 – John1024

1

这实际上会使>两个事情,打开一个文件或运行一个新的程序,这取决于操作数是什么。 (忽略的模糊性时的说法是一个可执行文件的名称:我们覆盖它或运行它?)


bash和其他一些shell提供额外的语法(进程替换),它在技术上更换需要|,虽然不是你会选择通过管道使用它。比如,你可以写

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) 
+0

++有关进程替换的信息。在语法上,它又归结为简单命令语法:'|','>(...)'和'<(...)'期望一个_command_,(简单)命令的第一个标记明确地是一个_命令名称_。 – mklement0

+0

允许我这个切线:至于其他shell支持哪些进程替换:'zsh'和'ksh'都接受_syntax_;然而,虽然'echo foo>>(cat)'的输出是'foo',正如所料,'bash'和'zsh','ksh'中是_empty_ - 为什么? – mklement0

+1

我不确定。你的问题让我想到了一个我曾经发现的问题(现在逃避了我)在'bash'和'zsh'之间如何实现进程替换。我认为两者之间的共同点是,由于流程替换不是由标准定义的,因此每个shell的实现都会以不同的方式处理各种转角情况。 – chepner