Como depurar um script bash?

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

  • -v também pode ajudar (imprime cada linha conforme são executadas. pode ser combinado com -x). E veja também: bashdb.sourceforge.net
  • outro recurso maravilhoso é: shellcheck .net
  • O que ” exec 5 > ” faz?
  • @aggsol: Se você usar BASH_XTRACEFD="5" bash grava a saída de rastreamento gerada quando set -x é habilitado para descritor de arquivo 5. exec 5> >(logger -t $0) redireciona a saída do descritor de arquivo 5 para logger comando.
  • Gostaria de saber se você pode obter o número da linha e o caminho ou nome do shell script no PS4?

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:

        ss1

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 o say 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.

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):

  1. Criar projeto de script Shell: Arquivo -> Novo -> Outro – > Script Shell

-> Assistente de projeto de script de shell .

  • Crie um arquivo de script Bash: Arquivo -> Novo -> Arquivo . Para este exemplo, será script.sh. A extensão deve ser “.sh” e é obrigatória.
  • Copie o arquivo _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

    insira a descrição da imagem aqui

    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.

    Captura de tela de depuração do VS Code Bash

    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 

    Deixe uma resposta

    O seu endereço de email não será publicado. Campos obrigatórios marcados com *