Assine a Lista Dicas-L
Receba diariamente por email as dicas
de informática publicadas neste site
Para se descadastrar, clique aqui.
Problemas IDIOTAMENTE comuns quando se cria um script em Shell
Colaboração: Rafael Henrique da Silva Correia
Data de Publicação: 18 de junho de 2012
Olhando o script abaixo (sem escrevê-lo no Shell :P) o que você diria que ele escreve na tela?? Lembrando que a variável $? informa o retorno do status do último comando se o comando executou com sucesso ele será 0, se o comando deu algum erro ele será diferente de 0. Olhe:
#!/bin/bash
echo "TESTANDO 123..."
if [ "$?" -ne 0 ]; then
echo "não igual a 0"
elif [ "$?" -eq 0 ]; then
echo "igual a 0"
else
echo "Nem um nem outro"
fi
Se você achou (assim como eu achei) que ele escreveria na tela "não igual a 0" você está redondamente enganado! Descobri que cometi um erro deste tipo em um script que eu estava fazendo (com certeza muuuuito maior do que este).
Por que o script tem este comportamento?
A variável $? como citado acima informa o retorno do status do último comando
se o comando executou com sucesso ele será 0, se o comando deu algum erro ele
será diferente de 0 .... porém o if faz uso do comando test (representado
por []), então o primeiro if retornará um status e esse novo status será
armazenado dentro de $?, desta forma DESGRAÇANDO todo o script.
E para corrigir?
Para corrigir basta criar uma variável auxiliar desta forma:
#!/bin/bash
echo "TESTANDO 123..."
VARAUX="$?"
if [ "$VARAUX" -ne 0 ]; then
echo "não igual a 0"
elif [ "$VARAUX" -eq 0 ]; then
echo "igual a 0"
else
echo "Nem um nem outro"
fi
Eis que agora a saída do script será:
rafael@zion:~$ ./teste1.sh TESTANDO 123... igual a 0
Como depurar programas em shell?
Geralmente no caso deste problema eu faria o seguinte, escreveria echos para ver o conteúdo da variável $? durante a execução do script da seguinte maneira:
#!/bin/bash
echo "TESTANDO 123..."
echo "$?"
if [ "$VARAUX" -ne 0 ]; then
echo "$?"
echo "não igual a 0"
elif [ "$VARAUX" -eq 0 ]; then
echo "$?"
echo "igual a 0"
else
echo "$?"
echo "Nem um nem outro"
fi
E para finalizar existe um parâmetro muito bom do bash próprio para fins de depuração:
rafael@zion:~$ bash -x teste1.sh + echo 'TESTANDO 123...' TESTANDO 123... + echo 0 0 + '[' '' -ne 0 ']' teste1.sh: line 6: [: : esperado expressão de número inteiro + '[' '' -eq 0 ']' teste1.sh: line 11: [: : esperado expressão de número inteiro + echo 2 2 + echo 'Nem um nem outro' Nem um nem outro
Desta forma você conseguirá ver que rumo seu script está tomando!
Esta dica não é nada complexa, porém agradeço se alguém postar outras formas de depuração de scripts em shell, eu somente iniciei o assunto e aqui no Dicas-l já li muitos comentários legais e construtivos a respeito das dicas que eu já postei!
Conhecimento traz conhecimento! Vamos colaborar!
Até+
Referências Adicionais
Referências adicionais sobre os assuntos abordados neste site podem ser encontradas em nossa Bibliografia.
Avalie esta dica
Opinião dos Leitores
28 Jun 2012, 08:43
comando desejado && echo "ok" || echo "deu pau no comando"
Porém se eu tenho que testar 3 ou 4 comandos usando and e or isso fica muito complicado. Quando eu jogo o valor do status em uma variável consigo usar os ifs da forma que eu desejar.
Até+
28 Jun 2012, 08:40
28 Jun 2012, 08:39
28 Jun 2012, 08:38
28 Jun 2012, 08:37
#!/bin/bash
echo "TESTANDO 123..."
VARAUX="$?"
if [ "$VARAUX" -ne 0 ]; then
echo "não igual a 0"
elif [ "$VARAUX" -eq 0 ]; then
echo "igual a 0"
else
echo "Nem um nem outro"
fi
Portanto O VARAUX vai pegar o status do comando echo, pois este é o objetivo do script.
27 Jun 2012, 07:35
Seu titulo não ficou bom.
18 Jun 2012, 18:40
18 Jun 2012, 16:21
# Debug
# set -xv
Sim, o comando "set" acima está comentado. Para ativá-lo basta descomentar a linha. Mas porque "-xv" e não "-x" ? Porque o "-v" vai listar a linha de comando *antes* da expansão/substituição, mostrando a linha antes e depois podemos verificar se a substituição foi a que se queria.
No caso específico deste tipo de código me parece só haver 2 possibilidades para a comparação, ou é igual a zero ou diferente. A opção "nenhum dos dois" não parece ter muita utilidade. Portanto bastaria haver as cláusulas "if" e "else", o que torna necessária a variável VARAUX.
Atenção, eu não estou dizendo que a variável não tem utilidade ! Em várias situações existe mesmo a necessidade. Por razões históricas, do tempo que trilobita era tira-gosto, eu uso RC (return code, coisa de mainframe, imagine só. :)). No caso de querer tratar vários valores eu uso algo como :
<comando>
RC=$?
case "$RC" in
0) echo "Tudo bem..."
;;
[1-5]) echo "Erro entre 1 e 5"
;;
127) echo "Arquivo não encontrado"
;;
*) echo "Erro $RC desconhecido, abortando."
exit $RC
;;
esac
Provavelmente a interface WEB vai destruir a estruturação do texto, mas acho que vai dar para entender. :)
18 Jun 2012, 15:21
18 Jun 2012, 12:23
Por exemplo, em scripts que necessitem criar um diretório, faço da seguinte maneira:
[ -d /path/do/diretorio ] || mkdir /path/do/diretorio
Aqui ele verificará se o diretório existe. Caso não, ele o criará.
18 Jun 2012, 07:25
18 Jun 2012, 06:54
comando desejado && echo "ok" || echo "deu pau no comando"
caso o comando dê certo o shell mostra ok, caso contrário
ele vai para o "ou" mostrando a mensagem de erro




