Digamos que eu tenha o seguinte pipeline:
cmd1 < input.txt |\
cmd2 |\
cmd4 |\
cmd5 |\
cmd6 |\
(...) |\
cmdN > result.txt
Sob certas condições, gostaria de adicionar um cmd3
entre cmd2
e cmd4
. Existe uma maneira de criar um pipeline condicional tipo sem salvar o resultado do cmd2 em um arquivo temporário? Eu pensaria em algo como:
cmd1 < input.txt |\
cmd2 |\
(${DEFINED}? cmd3 : cat ) |\
cmd4 |\
cmd5 |\
cmd6 |\
(...) |\
cmdN > result.txt
Respostas:
Apenas o habitual
&&
e||
operadores:(Observe que nenhuma barra invertida à direita é necessária quando a linha termina com tubo.)
Atualização de acordo com a observação de Jonas .
Se o cmd3 puder terminar com um código de saída diferente de zero e você não desejar
cat
processar a entrada restante, inverta a lógica:fonte
cat
retornar com um status de saída diferente de zero (comum ao obter um SIGPIPE),cmd3
será executado. É melhor usar if / then / else como na resposta de Thor ou outras soluções que evitam a execuçãocat
.if
/else
/fi
Obras. Supondo que qualquer shell tipo Bourne:fonte
Todas as respostas dadas até agora são substituídas
cmd3
porcat
. Você também pode evitar executar qualquer comando com:Esse é o POSIX, mas observe que, se em um
bash
script ondebash
não está emsh
-mode (como em um script começando com#! /path/to/bash
), você precisará ativar a expansão de alias comshopt -s expand_aliases
(ouset -o posix
).Outra abordagem que ainda não executa nenhum comando desnecessário é usar eval:
Ou:
No Linux (pelo menos), em vez de
cat
, você pode usar ospv -q
usos emsplice()
vez deread()
+write()
para passar os dados entre os dois canais, evitando que os dados sejam movidos duas vezes entre o kernel e o espaço do usuário.fonte
Como um adendo à resposta aceita pela manatwork : esteja ciente do e-false-or gotcha e de sua interação com os fluxos. Por exemplo,
saídas
foo
. Não surpreendentemente,e
ambos de saída
baz
. (Observe queecho foo | grep bar
é falso e não tem saída). Contudo,não produz nada. Isso pode ou não ser o que você deseja.
fonte
else
(ou||
) deve atuar como uma operação nula, mantendo a entrada inalterada. Portanto, substituircat
porecho
alterações tudo torna seu código irrelevante. Em relação ao “and-false-or gotcha”, não vejo interferência no pipeline: pastebin.com/u6Jq0bZe[[ "${DEFINED}" ]] && cmd3 || cat
,cmd3
ecat
não são o mutuamente exclusivasthen
eelse
ramos da mesmaif
, mas que, secmd3
falhar, entãocat
também será executado. (Claro, secmd3
sempre tem sucesso, ou se consome toda a entrada de modo que não há nada deixado emstdin
paracat
para processar, então o que pode não importa.) Se você precisa de ambosthen
eelse
filiais, é melhor usar um explícitaif
de comando, não&&
e||
.Eu tive uma situação semelhante que resolvi com as funções do bash :
fonte
Aqui está uma solução alternativa possível:
concatenando pipes nomeados para criar um pseudo-pipeline:
fonte
Para referência futura, se você vier aqui procurando tubos condicionais em peixes , é assim que você faz:
fonte