Pergunta
Qual é a semântica :
em relação ao seu uso em pipes?
A documentação do Bash afirma:
: [arguments]
Sem efeito; o comando não faz nada além de expandir os argumentos e executar quaisquer redirecionamentos especificados. O status de retorno é zero.
No entanto, não é óbvio qual comportamento devo esperar ao :
ser usado em um cachimbo. Ele simplesmente passa std{in,out,err}
?
No que diz respeito aos argumentos, :
pode ser um substituto para qualquer outro comando, ao que parece. Mas preciso de um esclarecimento quanto ao uso em cachimbo; um esclarecimento não meramente baseado na observação, mas citando fontes autorizadas .
Fundo
Eu tenho uma situação em que - dependendo do ambiente em que o script é executado -, preciso executar a saída tr -d '\r'
para remover os caracteres de retorno de carro da saída.
Infelizmente, atualmente isso significa um if/else/fi
bloco, ao longo das linhas de ( dentro de uma função ):
if [[ "$OSTYPE" == "cygwin" ]]; then
my_commands | tr -d '\r' || return $?
else
my_commands || return $?
fi
Onde o | tr -d '\r'
é a única diferença entre o if
e o else
ramo. O conteúdo de cada ramificação é obviamente um pouco mais complexo do que o mostrado aqui.
Agora, entendo que tr -d '\r'
é benigno nos casos em que não há retorno de carro. Mas é uma invocação e (no Windows) uma sobrecarga que pode ser evitada (a função é um caminho de código "quente"). E então pensei em substituir tr
pela função interna do shell :
.
A substituição de passagem neste caso é
cat
, que copia sua entrada para sua saída.:
não faz nada, então sua entrada seria perdida:Na verdade, como
:
não lê sua entrada, os comandos que alimentam o pipe receberão umSIGPIPE
, então eles podem não terminar sua tarefa ou até mesmo iniciá-la:Usar
cat
significa uma invocação externa, assim comotr
(mas com um pouco menos de trabalho). O Bash não possui um pass-through integrado desse tipo.Independentemente do nome estranho,
:
ainda é um comando e age como um, então quando não faz nada, significa que também não lê nada do pipe. Não é uma sintaxe especial para o shell no sentido de| : |
reduzir de volta para apenas|
. A descrição POSIX para:
diz que não "usa" stdin ou stdout, mas é claro que não menciona explicitamente os pipelines lá.Existem algumas soluções para isso no pipeline condicional , mas na maioria das vezes é difícil ou estranho evitar a execução de uma cópia
cat
no meio.(impressão fina: o texto POSIX usa o termo "utilitário", mas ainda é o mesmo termo usado para, por exemplo, .
ls
Além disso,:
não é exatamente um comando regular, mas um "embutido especial", que faz diferença em alguns casos, mas não aqui.)A frase-chave na página do manual é que
:
(como seu sinônimotrue
) não faz nada . Ele não lê nada de sua entrada, nem escreve nada em seus fluxos de saída.Em um cano, não é muito útil - age como um bloqueio no encanamento.