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 .
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
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.)