‘cmd1 | 的區別cmd2’ 和 ‘cmd2 <(cmd1)’ 和 ‘mkfifo foo;cmd1>富;cmd2 foo’?
或者:當 cmd2 可以同時使用兩者並且是單個命令時,何時以及為什麼不喜歡 STDIN?
我在這個網站上遇到了問題,他們的 3 個答案是上述每個答案之一,比如這個。這個問題作為第一個答案變體
mkfifo foo; cmd2 foo; cmd2<foo
。對我來說,相關的 3 個答案都讀起來像功能重複,但引擎蓋下的語義略有不同。每當我看到這一點時,我想知道後面的兩個答案是否應該是對第一個答案的編輯,或者到目前為止是否有一些真正重要的事情讓我無法理解。
以下是具體範例(關於“使用本地wireshark通過ssh嗅探遠端網路設備”):
使用 Fifo,原始答案(1):
$ mkfifo /tmp/remote; wireshark -k -i /tmp/remote $ ssh remote "tcpdump -s 0 -U -n -w - <moreOpts>" > /tmp/remote
用(過程替換)回答(2
<(...)
) :$ wireshark -k -i <(ssh remote tcpdump -s0 -U -n -w - <moreOpts>)
答案(3),帶有
|
(管道):$ ssh remote tcpdump -U -n -s0 <moreOpts> -w - | wireshark -k -i -
我自己通常會滿足於
cmd1 | cmd2
我的案例的版本,因為我也發現它更容易按順序閱讀。從來沒有理由深入探勘細節,但我可以模糊地記得一些關於變數、範圍、關於子 shell 緩衝的邊緣情況。
那麼,當我應該(不)使用表格 1、2 或 3 時,邊緣情況是什麼?
(1) 的一個範例是,如果 ssh 連結不穩定,則可以單獨重新啟動程序。但除此之外,關於何時不喜歡類型管道,我沒有看到/找到任何硬性規定。
主要區別在於各種命令在哪個 shell 中執行。由於兩者
ssh
和wireshark
無論如何都是外部程序,因此在語義上使用哪一個幾乎沒有區別。如果一個或兩個命令都是 shell 命令,則差異更重要。使用
mkfifo
,兩個命令都在目前 shell 實例中執行。使用管道,兩個命令都在從呼叫 shell 派生的子 shell 中執行。使用程序替換 (<(...)
),wireshark
由目前 shell 啟動,但ssh
在子 shell 中啟動。這會影響如何處理對變數的更改。考慮:
x=0; echo foo | { x=1; cat; }; echo "$x"
為 輸出值 0x
。x=0; { x=1; cat; } < <(echo foo); echo "$x"
輸出值 1 為x
在你的情況下,我會使用簡單的管道;不需要像程序替換這樣的非標準擴展。
ssh remote tcpdump -U -n -s0 <moreOpts> -w - | wireshark -k -i -