Isso ocorre porque o pipe pega o stdout e o canaliza para o próximo comando, o que você quer é o ponto-e-vírgula.
ls | grep -q foo; echo $?
Isso concluiu os comandos ls
e grep
e, em seguida, executa o comando echo
.
Eu estava escrevendo um script simples que verifica a saída de um comando que, se ele exibe uma determinada palavra-chave. Para ver se funciona, eu estava verificando o comando na linha de comando do bash.
$ ls | grep -q foo $ echo $?
A exibição 1 ou 0 depende da saída do comando e de um parâmetro grep como eu esperava.
Eu fico com pouca preguiça de digitar o comando novamente, então adicionei | echo $?
no final da linha de comando.
$ ls | grep -q foo | echo $?
Em seguida, independentemente da saída do comando, ele sempre retorna 0, mesmo se a primeira parte retornar 1.
Eu acho que isso é um comportamento normal, mas eu gostaria de saber porque o bash funciona dessa maneira.
A variável especial $?
expande para o status de saída do pipeline de primeiro plano executado mais recentemente . No seu exemplo, o | echo $?
é o pipeline de primeiro plano executado mais recentemente, nesse ponto, o status de saída do comando antes do último |
não está mais acessível por $?
.
Em uma nota relacionada, você pode usar o código de saída diretamente em instruções condicionais, por exemplo:
if ls | grep -q foo; then echo success, there is foo; fi
Ou, se você quiser executar algo no sucesso,
você poderia encadear o próximo comando usando &&
:
ls | grep -q foo && echo success
Tags command-line bash grep shell exit-code