Shell

‘cmd1 | 的區別cmd2’ 和 ‘cmd2 <(cmd1)’ 和 ‘mkfifo foo;cmd1>富;cmd2 foo’?

  • August 19, 2017

或者:當 cmd2 可以同時使用兩者並且是單個命令時,何時以及為什麼不喜歡 STDIN?

我在這個網站上遇到了問題,他們的 3 個答案是上述每個答案之一,比如這個。這個問題作為第一個答案變體mkfifo foo; cmd2 foo; cmd2&lt;foo

對我來說,相關的 3 個答案都讀起來像功能重複,但引擎蓋下的語義略有不同。每當我看到這一點時,我想知道後面的兩個答案是否應該是對第一個答案的編輯,或者到目前為止是否有一些真正重要的事情讓我無法理解。

以下是具體範例(關於“使用本地wireshark通過ssh嗅探遠端網路設備”):

使用 Fifo,原始答案(1)

$ mkfifo /tmp/remote; wireshark -k -i /tmp/remote
$ ssh remote "tcpdump -s 0 -U -n -w - &lt;moreOpts&gt;" &gt; /tmp/remote

用(過程替換)回答(2&lt;(...) ) :

$ wireshark -k -i &lt;(ssh remote tcpdump -s0 -U -n -w - &lt;moreOpts&gt;)

答案(3),帶有|(管道)

$ ssh remote tcpdump -U -n -s0 &lt;moreOpts&gt; -w - | wireshark -k -i -

我自己通常會滿足於cmd1 | cmd2我的案例的版本,因為我也發現它更容易按順序閱讀。

從來沒有理由深入探勘細節,但我可以模糊地記得一些關於變數、範圍、關於子 shell 緩衝的邊緣情況。

那麼,當我應該(不)使用表格 1、2 或 3 時,邊緣情況是什麼?

(1) 的一個範例是,如果 ssh 連結不穩定,則可以單獨重新啟動程序。但除此之外,關於何時不喜歡類型管道,我沒有看到/找到任何硬性規定。

主要區別在於各種命令在哪個 shell 中執行。由於兩者sshwireshark無論如何都是外部程序,因此在語義上使用哪一個幾乎沒有區別。

如果一個或兩個命令都是 shell 命令,則差異更重要。使用mkfifo,兩個命令都在目前 shell 實例中執行。使用管道,兩個命令都在從呼叫 shell 派生的子 shell 中執行。使用程序替換 ( &lt;(...)),wireshark由目前 shell 啟動,但ssh在子 shell 中啟動。

這會影響如何處理對變數的更改。考慮:

  1. x=0; echo foo | { x=1; cat; }; echo "$x"為 輸出值 0 x
  2. x=0; { x=1; cat; } &lt; &lt;(echo foo); echo "$x"輸出值 1 為x

在你的情況下,我會使用簡單的管道;不需要像程序替換這樣的非標準擴展。

ssh remote tcpdump -U -n -s0 &lt;moreOpts&gt; -w - | wireshark -k -i -

引用自:https://unix.stackexchange.com/questions/387179