Códigos de Saída: Usando $? e && ||
O que você vai conseguir fazer
- Verificar se o último comando teve sucesso ou falhou com `echo $?`
- Escrever as ramificações "se der certo" e "se falhar" com `&&` e `||`
- Informar sucesso ou falha a quem chamou usando `exit 0` e `exit 1`
Pré-requisitos (leia estes primeiro)
O Que Você Vai Aprender
- A ideia de um código de saída (exit status) que sinaliza sucesso ou falha
- Como verificar o resultado do comando anterior com
$? - Como ramificar com "se teve sucesso" e "se falhou" usando
&&e|| - Um primeiro passo para tratar erros corretamente em shellUm programa interativo que interpreta os comandos digitados e os executa. scripts
As palavras usadas aqui
- Código de saída: o número que um comando retorna ao terminar. Exit code, exit status e código de retorno nomeiam a mesma coisa.
- Variável: uma caixa com nome que guarda um valor. O
$?é uma variável especial que o shell preenche sozinho. - Shell script: um arquivo com comandos escritos em ordem.
Todos os comandos usados aqui -- ls, echo, cd, mkdir -- deixam os seus arquivos existentes em paz, então experimente à vontade.
Resumo Rápido
- Todo comando retorna um número quando termina (
0significa sucesso, qualquer outra coisa significa falha) - Quer ver o último resultado?
echo $? - Executar próximo em caso de sucesso ->
&& - Executar próximo em caso de falha ->
||
1. O Que é um Código de Saída?
Conclusão: Um código de saída é o número que um comando retorna.
0significa sucesso;1a255significam falha.
0 significa sucesso, qualquer outra coisa significa falha.A regra básica
| Número | Significado |
|---|---|
0 |
Sucesso |
1-255 |
Falha (algum problema) |
"0 significa sucesso" contraria a intuição. Fixe isso primeiro.
2. Por Que o Código de Saída Importa?
Conclusão: O código de saída é o que permite automatizar "executar o próximo passo apenas quando este teve sucesso."
Julgar o sucesso apenas pelo que é impresso na tela é arriscado. Um comando pode falhar mesmo quando nenhum texto "Error" aparece.
Confiar no código de saída, que a máquina consegue ler, é bem mais seguro.
3. Verificar o Resultado com $?
Conclusão:
$?contém o código de saída do último comando. Useecho $?para vê-lo.
O código de saída do comando que você acabou de executar fica em uma variável especial chamada $?. O shell a preenche sozinho.
$ ls /etc
hosts passwd ...
$ echo $?
0
0! Então ls teve sucesso.ls em um caminhoUma sequência de texto que descreve a localização de um arquivo ou diretório. que não existe.$ ls /not-exist
ls: cannot access '/not-exist': No such file or directory
$ echo $?
2
2. É um número diferente do anterior.0. O ls retorna 2 para o erro de "arquivo não encontrado".0 ou não.O $? guarda apenas o resultado do comando imediatamente anterior.
Execute echo $? duas vezes seguidas e o segundo reporta o primeiro echo. Aquele teve sucesso, então você recebe 0. Verifique apenas uma vez.
4. Encadear "em caso de sucesso" com &&
Conclusão:
cmd1 && cmd2executa cmd2 apenas quando cmd1 tem sucesso (retorna0).
O && é o símbolo que significa "se o lado esquerdo tiver sucesso, execute o lado direito também".
$ mkdir backup && cp data.txt backup/
cp apenas se o mkdir tiver sucesso"?mkdir backup falhar, o cp não executa. Isso acontece quando você não tem permissãoAs regras de acesso de leitura / escrita / execução definidas em um arquivo ou diretório. para criar o diretórioUm local que organiza arquivos. É a mesma ideia da "pasta" do Windows ou macOS., por exemplo.# Executar testes apenas se o build tiver sucesso $ make && make test # Listar o conteudo apenas se o cd tiver sucesso $ cd /var/log && ls
Pense no && como "prosseguir quando a pré-condição for atendida". Ele encadeia passos com segurança quando você quer parar assim que algo falhar.
5. Encadear "em caso de falha" com ||
Conclusão:
cmd1 || cmd2executa cmd2 apenas quando cmd1 falha. Use para tratamento de erros.
O || é o oposto do &&. Ele significa "se o lado esquerdo falhar, execute o lado direito".
$ cd /var/log || echo "Nao foi possivel entrar no diretorio"
cd falhar, ele imprime uma mensagem. E quando tem sucesso, nada é impresso?cd tiver sucesso, o echo nunca executa. O || costuma servir como uma rede de segurança para quando as coisas dão errado.# Sugerir instalacao se um comando estiver faltando $ which jq || echo "jq nao esta instalado. Por favor, instale-o." # Sair do script se o passo falhar $ cp data.txt backup/ || exit 1
&& vs || resumo visual
cmd1 && cmd2 -> cmd2 executa se cmd1 [tiver sucesso] cmd1 || cmd2 -> cmd2 executa se cmd1 [falhar]
Lembre assim: "&& prossegue em caso de sucesso" e "|| prossegue em caso de falha".
6. Combinando && e ||
Conclusão:
cmd && em-sucesso || em-falhaescreve "faça A em caso de sucesso, B em caso de falha" em uma linha.
Encadear && e || permite agir de um jeito em caso de sucesso e de outro em caso de falha.
$ ping -c1 example.com > /dev/null && echo "Conexao OK" || echo "Conexao NG"
echo "Conexao OK" -- a ação de falha executa também.if é mais seguro.A && B || C não é o mesmo que if A then B else C. Se B falhar, C também executa.
Quando você precisa de uma ramificação confiável, use uma instrução if. O artigo da próxima leitura explica como.
7. Armadilhas Comuns de Iniciantes
Conclusão: Os erros fáceis são inverter "0 significa sucesso" e ler
$?tarde demais.
7-1. Lembrar "0 significa sucesso" ao contrário
7-2. Lina se atrapalha: ler o $? tarde demais
$ ls /not-exist $ pwd # <- um comando extra escapou $ echo $? # isto mostra o resultado de pwd (0, sucesso)
0. O código de saída está quebrado?$? só lembra de um comando para trás.pwd que entrou no meio substituiu o valor?pwd tem sucesso, então o valor virou 0. O resultado do ls já tinha sido sobrescrito.Verifique o $? logo após o comando que você quer conferir. Qualquer comando entre eles sobrescreve o valor.
7-3. Retornando um código de saída você mesmo
Quando você quer que um script informe sucesso ou falha a quem o chamou, use exit.
exit 0 # encerrar como sucesso exit 1 # encerrar como falha
Se você chamar exit sem um número, ele retorna o código de saída do último comando como está.
8. Exercícios Práticos
Conclusão: Três exercícios — verificar, executar em sucesso, executar em falha — para praticar
$?,&&e||.
Exercício 1: Execute um comando e, logo em seguida, mostre o código de saída dele.
Ver Dica 1 (Direção)
O último resultado fica em uma variável especial que o shell preenche. Mostre o conteúdo dela na tela.
Ver Dica 2 (Nome do comando)
A variável é $?. Mostre com echo.
Ver Resposta
$ ls $ echo $?
0
O ls teve sucesso, então você recebe 0. Aponte para um diretório que não existe e o número muda para algo diferente de 0.
Exercício 2: Mostre "Criado" apenas quando o mkdir test-dir tiver sucesso.
Ver Dica 1 (Direção)
Junte dois comandos em uma linha. Use o símbolo que executa o lado direito somente quando o esquerdo tem sucesso.
Ver Dica 2 (Nome do comando)
O símbolo é &&. Mostre com echo.
Ver Resposta
$ mkdir test-dir && echo "Criado"
Criado
Execute a mesma linha uma segunda vez e o mkdir falha, então "Criado" não aparece. Remova o diretório depois com rmdir test-dir.
Exercício 3: Tente fazer cd em um diretório que não existe e mostre "Não foi possível mover" apenas quando falhar.
Ver Dica 1 (Direção)
Mesmo formato do Exercício 2, com o símbolo invertido. Use o que executa o lado direito somente quando o esquerdo falha.
Ver Dica 2 (Nome do comando)
O símbolo é ||. Para mover, use cd.
Ver Resposta
$ cd /not-exist || echo "Nao foi possivel mover"
bash: cd: /not-exist: No such file or directory Nao foi possivel mover
Você vê tanto a mensagem de erro do próprio cd quanto a mensagem que você mandou imprimir.
9. Revisão
0 é sucesso, qualquer outra coisa é falha.echo $?, mas só o do comando imediatamente anterior.&& prossegue em caso de sucesso, enquanto o || prossegue em caso de falha. Anotado.exit 0 e exit 1.10. Modelos para Copiar e Colar
Conclusão: Mantenha os padrões comuns — verificar, em sucesso, em falha, ramificar e sair — ao alcance.
Padrões comuns para ter à mão
# Verificar o ultimo codigo de saida echo $? # Executar proximo apenas em caso de sucesso commandA && commandB # Executar proximo apenas em caso de falha commandA || commandB # A em caso de sucesso, B em caso de falha (ramificacao simples) command && echo "OK" || echo "NG" # Sair do script se o passo falhar command || exit 1 # Encerrar um script explicitamente como sucesso / falha exit 0 # sucesso exit 1 # falha
Resumo do Dia em 3 Linhas
- Um comando retorna um número ao terminar.
0é sucesso, qualquer outra coisa é falha - Leia o último resultado com
echo $?, sem nenhum comando no meio - O
&&prossegue em caso de sucesso. O||prossegue em caso de falha