Estou tendo alguns problemas com alguns scripts no bash, sobre erros e comportamentos inesperados. Gostaria de investigar as causas dos problemas para poder aplicar correções. Existe uma maneira de ativar algum tipo de “modo de depuração” para o bash, para obter mais informações?
Resposta
Inicie seu script bash com bash -x ./script.sh
ou adicione em seu script set -x
para ver a saída de depuração.
Adicional com bash
4.1 ou posterior:
Se você deseja gravar a saída de depuração em um arquivo separado, adicione ao seu script:
exec 5> debug_output.txt BASH_XTRACEFD="5"
Veja: https://stackoverflow.com/a/25593226/3776858
Se quiser ver os números das linhas, adicione:
PS4="$LINENO: "
Se você tiver acesso a logger
comando então você pode usar isso para escrever a saída de depuração através do seu syslog com carimbo de data / hora, nome do script e número da linha:
#!/bin/bash exec 5> >(logger -t $0) BASH_XTRACEFD="5" PS4="$LINENO: " set -x # Place your code here
Você pode usar a opção -p
do comando logger
para definir uma instalação e nível individual para gravar a saída via syslog local em seu próprio arquivo de log.
Comentários
Resposta
Usando set -x
Eu sempre uso set -x
e set +x
. Você pode envolver as áreas que deseja ver o que está acontecendo com elas para aumentar / diminuir a verbosidade.
#!/bin/bash set -x ..code to debug... set +x
log4bash
Também se você fez um trabalho de desenvolvimento e está familiarizado com o estilo de registradores que atendem pelos nomes log4j, log4perl, etc., convém usar log4bash .
excerto
Vamos enfrentá-lo – o velho echo simplesmente não resolve. log4bash é uma tentativa de ter um melhor registro para scripts Bash (ou seja, tornar o registro no Bash menos complicado).
A partir daí, você pode fazer coisas como esta em seu Scripts Bash:
#!/usr/bin/env bash source log4bash.sh log "This is regular log message... log and log_info do the same thing"; log_warning "Luke ... you turned off your targeting computer"; log_info "I have you now!"; log_success "You"re all clear kid, now let"s blow this thing and go home."; log_error "One thing"s for sure, we"re all gonna be a lot thinner."; # If you have figlet installed -- you"ll see some big letters on the screen! log_captains "What was in the captain"s toilet?"; # If you have the "say" command (e.g. on a Mac) log_speak "Resistance is futile";
Resultando neste tipo de saída:
log4sh
Se você precisa de algo mais portátil, também há os mais antigos log4sh
. Funciona semelhante a log4bash
, disponível aqui:
Comentários
- No Ubuntu, tenho
alias say="spd-say"
em meu .bashrc, que imita osay
comando de outras distros ou OS X. - set -vx seria uma boa combinação se usado com trap – trap read debug. Isso permite que você avance linha por linha e veja os resultados
Resposta
Existe “um depurador bash, bashdb , que é um pacote instalável em muitas distros. Ele usa o modo de depuração estendido integrado do bash (shopt -s extdebug
). Parece muito com o gdb; aqui está um exemplo de sessão para dar uma ideia:
$ ls 1st.JPG 2ndJPG.JPG $ cat ../foo.sh for f in *.JPG do newf=${f/JPG/jpg} mv $f $newf done $ bashdb ../foo.sh (foo.sh:1): 1: for f in *.JPG bashdb<0> next (foo.sh:3): 3: newf=${f/JPG/jpg} bashdb<1> next (foo.sh:4): 4: mv $f $newf
Como no gdb, a instrução é mostrada apenas antes de ser executada. Portanto, podemos examinar as variáveis para ver o que a instrução fará antes de fazê-lo.
bashdb<2> print $f $newf 1st.JPG 1st.jpg bashdb<3> next (foo.sh:1): 1: for f in *.JPG bashdb<4> next (foo.sh:3): 3: newf=${f/JPG/jpg} bashdb<5> next (foo.sh:4): 4: mv $f $newf bashdb<6> print $f $newf 2ndJPG.JPG 2ndjpg.JPG
Não é isso que queremos! Vejamos o expansão do parâmetro novamente.
bashdb<7> print $f ${f/JPG/jpg} 2ndJPG.JPG 2ndjpg.JPG bashdb<8> print $f ${f/JPG$/jpg} 2ndJPG.JPG 2ndJPG.JPG bashdb<9> print $f ${f/%JPG/jpg} 2ndJPG.JPG 2ndJPG.jpg
OK, isso funciona. Vamos definir newf
com o valor correto.
bashdb<10> eval newf=${f/%JPG/jpg} $? is 0 bashdb<11> print $f $newf 2ndJPG.JPG 2ndJPG.jpg
Parece bom. Continue o script.
bashdb<12> next Debugged program terminated normally. Use q to quit or R to restart. $ ls 1st.jpg 2ndJPG.jpg
Resposta
O método padrão para depurar scripts na maioria dos shells baseados em Bourne, como bash é escrever set -x
no início do seu script. Isso tornará o bash mais detalhado sobre o que está sendo feito / executado e como os argumentos são avaliados.
-x Print commands and their arguments as they are executed.
Isso é útil para o interpretador ou scripts internos. Por exemplo:
$ find "$fileloc" -type f -prune "$filename" -print + find /var/adm/logs/morelogs -type f -prune "-name *.user" -print find: unknown predicate "-name *.user" $ find "$fileloc" -type f -prune $filename -print + find /var/adm/logs/morelogs -type f -prune -name "*.user" -print find: "/var/adm/logs/morelogs": No such file or directory
Acima, podemos ver porque o find está falhando devido a algumas aspas simples.
Para desativar o recurso, basta digitar set +x
.
Resposta
Usando Eclipse
Você pode usar o ambiente combinado de Eclipse e Shelt com o script “_DEBUG.sh” com link abaixo.
- Plug-in Eclipse Shelled:
http://sourceforge.net/projects/shelled/files/shelled/update/ - depurador bash – funciona apenas com shell:
http://sourceforge.net/projects/basheclipse/
Alternando shells
Por padrão, a ferramenta de desenvolvimento Shelled usa /bin/dash
como interpretador. Mudei isso para /bin/bash
para ter melhor compatibilidade com a maioria dos exemplos de shell na web e meu ambiente.
OBSERVAÇÃO: Você pode alterar isso acessando: Window -> Preferência -> Shell Script -> Intérpretes
Instruções de configuração
O pacote do Depurador tem as etapas para usar o script _DEBUG.sh
para depurar o seu script, que é basicamente (o readme.txt):
- Criar projeto de script Shell: Arquivo -> Novo -> Outro – > Script Shell
-> Assistente de projeto de script de shell .
script.sh
. A extensão deve ser “.sh” e é obrigatória. _DEBUG.sh
para a pasta do projeto. Insira o seguinte texto no topo do arquivo script.sh
:
. _DEBUG.sh
Se o arquivo é criado no Microsoft Windows e certifique-se de executar o Arquivo -> Converter delimitadores de linha em -> Unix .
Defina uma configuração de inicialização de depuração: Execute -> Configurações de depuração -> Script Bash … Existem 2 campos a serem definidos aqui:
a) “Script Bash:” – Caminho na área de trabalho do Eclipse para o script Bash a ser depurado.
e) “Porta do depurador:” 33333
Mude para a perspectiva de depuração. Inicie a sessão de depuração. Inicie script.sh
a partir do shell bash.
A IU de depuração do bash
Este depurador bash tem todos os recursos de depuradores de programação padrão, como:
- Alternância de ponto de interrupção
- Operação passo a passo única
- Funções e sub-rotinas Step-in, Step-out, Step-over
- Examinar código ou variáveis em qualquer ponto enquanto o script está em execução
O Shelt (Editor de Shell Script) IDE (Ambiente de Desenvolvimento Integrado) tem um bônus adicional de execução de verificação de contexto, realce e recuo ao escrever seu script. Se não houver indentação correta, você poderá imediatamente sinalizar / localizar muitos erros lá.
Então, há outros benefícios do IDE como:
- lista de tarefas TODO
- tarefa Mylyn
- lista de favoritos
- vários Edição de janelas
- Compartilhamento remoto do ambiente
Comentários
- Dica legal. É bom saber que o Bash pode ser depurado assim.
Resposta
Um recurso maravilhoso apareceu nos últimos anos: http://shellcheck.net
mostra a você mais do que a bash normal, permitindo encontrar facilmente aquelas aspas não fechadas irritantes ou curvas colchetes, etc.
Apenas certifique-se de não colar informações confidenciais (ips, senhas, etc) na rede … (especialmente porque é http, não criptografado) (acredito que o shellcheck também está disponível para fazer o download, mas não tenho certeza)
Resposta
Hoje em dia, existe o VS Code Bash Debug.
https://marketplace.visualstudio.com/items?itemName=rogalmic.bash-debug
Possui “Step in / out / sobre “e também mostra o valor de cada variável.
Comentários
- esta resposta não aborda a pergunta no contexto certo; assumindo a linha de comando já que o IDE não foi mencionado
Resposta
simplesmente use:
#!/bin/bash -x
o mesmo para shell:
#!/bin/sh -x
BASH_XTRACEFD="5"
bash grava a saída de rastreamento gerada quandoset -x
é habilitado para descritor de arquivo 5.exec 5> >(logger -t $0)
redireciona a saída do descritor de arquivo 5 paralogger
comando.