2015-11-04 77 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