Eu vi uma expressão como command1 | {command2;command3;command4}
e estava pensando o que isso realmente significa, eu conheço o símbolo da barra vertical, sei que isso {...}
força a execução dos comandos dentro das chaves no shell principal, mas estou confuso sobre o que eles significam em combinação.
Responder1
Realmente não importa quão complexas sejam as partes de um pipeline, muitas vezes você pode visualizá-las como scripts separados, se desejar (especialmente em shells como bash
os que executarão cada parte de um pipeline em um subshell de qualquer maneira).
O roteiro
command2
command3
command4
... qualaproximadamenteé o que { command2; command3; command4; }
se traduz em (sem levar em conta que { ...; }
nominalmente significa que os comandos não são executados em um subshell), recebe a entrada da execução de
command1
Dependendo do que esses três comandos no primeiro script estão fazendo, um ou vários deles provavelmente consumirão a entrada de command1
, e se um ou vários deles estiverem produzindo alguma saída, isso irá para a próxima parte do pipeline, ou para o terminal ou para onde quer que a saída do pipeline seja redirecionada.
Responder2
{...}
força a execução dos comandos dentro das chaves no shell principal
Esta não é uma boa descrição do que os aparelhos fazem em geral. Chaves agrupam comandos de uma forma que não cria um subshell. Em outras palavras, os colchetes por si só não criam um subshell: o código entre colchetes é executado no mesmo shell como se não houvesse colchetes, ao contrário do código entre parênteses que é sempre executado em um subshell (portanto, seus redirecionamentos, variáveis, e assim por diante não afetam o shell pai ou qualquer outro shell).
O objetivo dos colchetes é permitir a escrita de comandos complexos onde a sintaxe espera um único comando. Por exemplo, in command1 | { command2; command3; command4; }
(observe que os espaços e o ponto e vírgula final são necessários), o lado direito do tubo é { command2; command3; command4; }
. O comando { command2; command3; command4; }
é executado command2
, então command3
, então command4
. Todos esses comandos recebem informações do pipe. (Como os comandos são executados sucessivamente, command3
obtém qualquer entrada restante após command2
as execuções e assim por diante.)
Responder3
pense nas chaves como uma função sem nome. por exemplo
command234 () { command2; command3; command4; }
command1 | command234
dá o mesmo resultado. quando as coisas ficam muito complicadas, prefiro nomear o agrupamento. mesmo que apenas para teste.
Responder4
A saída padrão de command1
será usada para o primeiro comando no bloco de comando que inicia a leitura da entrada padrão. Na maioria dos casos, isso será command2
.