Pipe B para D? - A && B || C | D

13

Existe uma maneira de reescrever a estrutura de comando A && B || C | D para que B ou C sejam canalizados para D?

Com o comando atual, apenas B ou C e D são executados.

Por exemplo:

    
por Philip Kirkbride 17.04.2017 / 14:54

3 respostas

30

Sim, no bash você pode usar parênteses:

(A && B || C) | D

Dessa forma, a saída de A && B || C será canalizada para D .

    
por 17.04.2017 / 14:59
14

Você pode escrever isso como

if A; then B; else C; fi | D

Você diz que deseja executar B ou C , mas A && B || C não consegue isso. Se A for bem-sucedido, mas B for executado e falhar, ele executará C .

Nota 1: se você puder de alguma forma garantir que B sempre tenha sucesso e queira continuar com uma versão curta, eu ainda optaria por

{ A && B || C; } | D

acima de ( ... ) , pois o último força desnecessariamente a criação de um novo subshell, que pode ou não ser otimizado.

Nota 2: ambos os formulários assumem A não produz saída, o que é verdadeiro no seu exemplo, mas não necessariamente em geral. Isso pode ser evitado por

A; if [ "$?" -eq 0 ]; then B; else C; fi | D
    
por 17.04.2017 / 17:39
5

A resposta de aceitação está correta, mas não abrange o possível caso de uso para não ter a saída de A como entrada de D . Para conseguir isso, você precisará de um redirecionamento de fluxo em A , dependendo de suas necessidades.

  • Se você quiser descartar a saída de A de qualquer maneira:

    { A >/dev/null && B || C; } | D
    
  • Se você quiser ver a saída de A no terminal:

    { A >/dev/tty && B || C; } | D
    
  • Se você precisar da saída de A como entrada de um comando subseqüente E , precisará de um grupo de comando adicional e redirecionamento de fluxo:

    { { A >&3 && B || C; } | D; } 3>&1 | E
    

Se tudo isso parece muito estranho para você (como para mim), eu recomendo que você use a variável shell especial para o status de saída de A e trabalhe com isso:

A
if [ $? -eq 0 ]; then
  B
else
  C
fi |
D

Se você quer ser mais conciso, mas não muito arcaico, sugiro isso:

A; { [ $? -eq 0 ] && B || C; } | D

(Veja também a última parte da resposta do hvd que não notei quando escrevi minha resposta original.)

    
por 17.04.2017 / 22:08

Tags