Existe uma maneira de reescrever a estrutura de comando A && B || C | Dpara que B ou C seja canalizado para D?
Com o comando atual, apenas B ou C e D são executados.
Por exemplo:
Existe uma maneira de reescrever a estrutura de comando A && B || C | Dpara que B ou C seja canalizado para D?
Com o comando atual, apenas B ou C e D são executados.
Por exemplo:
Respostas:
Sim, no bash você pode usar parênteses:
(A && B || C) | D
Dessa forma, a saída de A && B || Cserá canalizada D.
sh:)
Aestá dentro da subcamada, este também inclui A.)
Você pode escrever isso como
if A; then B; else C; fi | D
Você diz que deseja executar um Bou outro C, mas A && B || Cnão consegue isso. Se Afor bem-sucedido, mas for Bexecutado e falhar, ele será executado C.
Nota 1: se você, de alguma forma, pode garantir que Bsempre seja bem-sucedido e queira continuar com uma versão curta, eu ainda optaria por
{ A && B || C; } | D
acabou ( ... ), pois o último força desnecessariamente a criação de um novo subshell, que pode ou não ser otimizado.
Nota 2: ambas as formas assumem que Anão produz saída, o que é verdade no seu exemplo, mas não necessariamente no geral. Isso pode ser evitado por
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
{ … }não força a criação de um subshell devido ao pipe? I observar o seguinte comportamento: pgrep bashe pgrep bash | cate if true; then pgrep bash; fie { pgrep bash; }têm uma linha de saída; ( pgrep bash; )e ( pgrep bash; ) | cate { pgrep bash; } | cate if true; then pgrep bash; fi | cattem duas linhas de saída.
... | ...faz com que um subshell seja criado, isso é inevitável. ( ... ), pelo menos em teoria, faz com que seja criado um subshell adicional que { ...; }evite, mas é isso que eu quis dizer com "pode ou não ser otimizado": é possível que, nesse caso em particular, o shell perceba que não importa, o efeito seria o mesmo.
A resposta do aceitador está correta, mas não cobre o caso de uso potencial para não ter a saída Acomo entrada de D. Para conseguir isso, você precisará de um redirecionamento de fluxo, Adependendo de suas necessidades.
Se você deseja descartar a saída de Aqualquer maneira:
{ A >/dev/null && B || C; } | DSe você deseja ver a saída do Aterminal:
{ A >/dev/tty && B || C; } | DSe você precisar da saída Acomo entrada de um comando subsequente, Eprecisará de um grupo de comandos adicional e redirecionamento de fluxo:
{ { A >&3 && B || C; } | D; } 3>&1 | ESe tudo isso parecer muito misterioso para você (como para mim), recomendo que você use a variável especial do shell para o status de saída Ae trabalhe com isso:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
Se você quer ser mais conciso, mas não muito misterioso, sugiro o seguinte:
A; { [ $? -eq 0 ] && B || C; } | D
(Veja também a última parte da resposta do hvd que eu não notei quando escrevi minha resposta original.)
Asaí do pipeline.
A && (B || C) | D, se você não quer B, C ou D para ser executado quando uma falha