Codigos de Saida: Usando $? e && ||
O Que Voce Vai Aprender
- A ideia de um codigo de saida (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 shell scripts
Resumo Rapido
- Todo comando retorna um numero quando termina (
0significa sucesso, qualquer outra coisa significa falha) - Quer ver o ultimo resultado?
echo $? - Executar proximo em caso de sucesso ->
&& - Executar proximo em caso de falha ->
||
1. O Que e um Codigo de Saida?
Conclusao: Um codigo de saida e o numero que um comando retorna.
0significa sucesso;1a255significam falha.
0 significa sucesso, qualquer coisa diferente de 0 significa falha. Esse unico numero diz se o comando funcionou.A regra basica
| Numero | Significado |
|---|---|
0 |
Sucesso |
1-255 |
Falha (algum problema) |
"0 significa sucesso" e contraintuitivo, entao fixe isso primeiro.
2. Por Que o Codigo de Saida Importa?
Conclusao: O codigo de saida e o que permite automatizar "executar o proximo passo apenas quando este teve sucesso."
Julgar sucesso apenas pelo que e impresso na tela e arriscado. Um comando pode falhar mesmo quando nenhum texto "Error" aparece. Confiar no codigo de saida legivel por maquina e muito mais confiavel.
3. Verificar o Resultado com $?
Conclusao:
$?contem o codigo de saida do ultimo comando. Useecho $?para ve-lo.
O codigo de saida do comando que voce acabou de executar e armazenado na variavel especial $?.
$ ls /etc
hosts passwd ...
$ echo $?
0
0! Entao ls teve sucesso.ls em um caminho que nao existe.$ ls /not-exist
ls: cannot access '/not-exist': No such file or directory
$ echo $?
2
2. Um numero diferente do anterior!0. ls retorna 2 para erro de "arquivo nao encontrado". Voce nao precisa decorar os numeros exatos — apenas se e 0 ou nao.$? guarda apenas o resultado do comando imediatamente anterior. Executar echo $? duas vezes seguidas faz com que o segundo mostre "o codigo de saida do primeiro echo (que teve sucesso, entao 0)." Verifique apenas uma vez.
4. Encadear "em caso de sucesso" com &&
Conclusao:
cmd1 && cmd2executa cmd2 apenas quando cmd1 tem sucesso (retorna0).
&& significa "se o lado esquerdo tiver sucesso, execute o lado direito tambem."
$ mkdir backup && cp data.txt backup/
cp apenas se mkdir tiver sucesso"?mkdir backup falhar (digamos, voce nao tem permissao para cria-lo), cp nao sera executado. Use quando um passo depende do anterior ter sucesso.# 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 em && como "prosseguir quando a pre-condicao for atendida." Ele encadeia passos com seguranca onde voce quer parar se algo falhar.
5. Encadear "em caso de falha" com ||
Conclusao:
cmd1 || cmd2executa cmd2 apenas quando cmd1 falha. Use para tratamento de erros.
|| e o oposto de &&: significa "se o lado esquerdo falhar, execute o lado direito."
$ cd /var/log || echo "Nao foi possivel entrar no diretorio"
cd falhar, imprime uma mensagem. E se tiver sucesso, nenhuma mensagem?cd tiver sucesso, o echo nunca executa. || e frequentemente usado como uma rede de seguranca para quando as coisas dao 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-se: "&& prossegue em caso de sucesso," "|| prossegue em caso de falha."
6. Combinando && e ||
Conclusao:
cmd && em-sucesso || em-falhaescreve "faca A em caso de sucesso, B em caso de falha" em uma linha.
Encadear && e || permite agir de forma diferente em caso de sucesso ou falha.
$ ping -c1 example.com > /dev/null && echo "Conexao OK" || echo "Conexao NG"
echo Conexao OK) falhar, a acao de falha tambem executa. E aceitavel para mensagens simples, mas para algo complexo, um if e mais seguro.A && B || C nao e estritamente identico a "if A then B else C." Se B falhar, C tambem executa. Quando voce precisa de ramificacao confiavel, use uma instrucao if (veja o artigo relacionado).
7. Armadilhas Comuns de Iniciantes
Conclusao: Os erros faceis sao inverter "0 significa sucesso" e ler
$?tarde demais.
7-1. Lembrar "0 significa sucesso" ao contrario
7-2. Ler $? tarde demais
$ ls /not-exist $ pwd # <- um comando extra escapou $ echo $? # isto mostra o resultado de pwd (0, sucesso)
Verifique $? logo apos o comando que voce quer verificar. Qualquer comando entre eles sobrescreve $?.
7-3. Retornando um codigo de saida voce mesmo
Quando voce quer que um script ou comando reporte sucesso ou falha ao chamador, use exit.
exit 0 # encerrar como sucesso exit 1 # encerrar como falha
Se voce chamar exit sem um numero, ele retorna o codigo de saida do ultimo comando como esta.
8. Exercicios Praticos
Conclusao: Tres exercicios — verificar, executar em sucesso, executar em falha — para praticar
$?,&&e||.
Exercicio 1: Execute qualquer comando (ex.: ls), depois imprima seu codigo de saida logo em seguida.
Mostrar dica
O ultimo resultado esta em $?.
Resposta exemplo
$ ls $ echo $?
Exercicio 2: Imprima "Criado" apenas quando mkdir test-dir tiver sucesso.
Mostrar dica
"Executar proximo em caso de sucesso" e &&.
Resposta exemplo
$ mkdir test-dir && echo "Criado"
Exercicio 3: Tente fazer cd em um diretorio que nao existe e imprima "Nao foi possivel mover" se falhar.
Mostrar dica
"Executar proximo em caso de falha" e ||.
Resposta exemplo
$ cd /not-exist || echo "Nao foi possivel mover"
9. Modelos para Copiar e Colar
Conclusao: Mantenha os padroes comuns — verificar, em sucesso, em falha, ramificar e sair — ao alcance.
Padroes comuns para ter a mao
# 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