Diferença entre 'cmd1 | cmd2 'e' cmd2 (cmd1) 'e' mkfifo foo; cmd1foo; cmd2 foo '?

0

Ou: Quando e por que não preferir STDIN quando o cmd2 pode usar ambos e é um único comando?

Eu me deparei com perguntas neste site, onde 3 de suas respostas são uma das opções acima, como este . Esta questão teve como primeira resposta variante mkfifo foo; cmd2 foo; cmd2<foo .

Para mim, as três respostas em questão são lidas como duplicatas funcionais com pequenas diferenças na semântica sob o capô. Sempre que vejo isso, me pergunto se as duas respostas anteriores deveriam ter sido editadas na primeira, ou se algo realmente significativo me iludiu até agora.

Aqui estão os exemplos específicos (Sobre "Farejando dispositivos de rede remotos via ssh com wireshark local"):

Com Fifo, resposta original (1) :

$ mkfifo /tmp/remote; wireshark -k -i /tmp/remote
$ ssh remote "tcpdump -s 0 -U -n -w - <moreOpts>" > /tmp/remote

Responda (2) com <(...) (substituição do processo) :

$ wireshark -k -i <(ssh remote tcpdump -s0 -U -n -w - <moreOpts>)

Responda (3), com | (tubulação) :

$ ssh remote tcpdump -U -n -s0 <moreOpts> -w - | wireshark -k -i -

Eu mesmo geralmente aceito a versão cmd1 | cmd2 dos meus casos, porque também acho mais fácil ler sequencialmente.

Nunca houve motivo para pesquisar detalhes específicos, mas posso lembrar-me vagamente de alguns casos de limites relativos a variáveis, escopo, buffering em relação a sub-shells.

Então, quais são os casos de borda, quando devo | poder (não) usar os formulários 1,2 ou 3?

Um exemplo para (1) seria que os processos podem ser reiniciados individualmente, se, e. o link ssh é esquisito. Mas, além disso, não vejo / acho nenhuma regra dura e rápida, sobre quando não preferir o tipo de tubulação.

    
por Alex Stragies 19.08.2017 / 20:12

1 resposta

1

A principal diferença é em qual shell os vários comandos são executados. Já que ssh e wireshark são processos externos, faz pouca diferença semanticamente qual deles você usa.

A diferença é mais relevante se um ou ambos os comandos forem de shell. Com mkfifo , ambos os comandos são executados na instância atual do shell. Com um pipe, ambos os comandos são executados em subshells bifurcados do shell de chamada. Com a substituição do processo ( <(...) ), wireshark é iniciado pelo shell atual, mas ssh é iniciado em um subshell.

Isso pode afetar como as mudanças nas variáveis são tratadas. Considere:

  1. x=0; echo foo | { x=1; cat; }; echo "$x" produz um valor de 0 para x .
  2. x=0; { x=1; cat; } < <(echo foo); echo "$x" gera um valor de 1 para x

No seu caso, eu usaria o pipeline simples; não há necessidade de extensões não padrão, como substituição de processos.

ssh remote tcpdump -U -n -s0 <moreOpts> -w - | wireshark -k -i -
    
por 19.08.2017 / 20:28