Como depurar o script bash?

31

Existe alguma maneira de depurar o script bash sem usar eco e log?

Estou falando sobre o uso de pontos de interrupção e coisas assim.

UAdapter
fonte

Respostas:

20

Existem várias maneiras diferentes, ou seja:

  • Execute seu script com a opção -x

    bash -x yourscript.sh
  • Adicione set -xuma nova linha no início do seu arquivo #!/bin/bashde script após o Shebang e antes do início do seu script, set -vexibirá as linhas de entrada do shell, set -xexibirá os comandos e argumentos executados

  • substitua o shebang do seu arquivo de script por #!/bin/bash -xv

NES
fonte
4

Você pode usar esta pequena função para entrar no "console":

function debug
{
    echo "#############|  Entering DEBUG mode  |####################";
    cmd=""
    while [[ $cmd != "exit" ]]; do
        read -p "> " cmd
        case "$cmd" in
            vars ) ( set -o posix ; set );;
            exit ) ;;
            * ) eval "$cmd";;
        esac
    done
    echo "#############|  End of DEBUG mode |####################";
}

Em seguida, dentro do seu script (EXEMPLO):

for file in *; do
...
   if [[ $file == "strange_case.txt" ]]; then
       # break the code here to analyze:
       debug
   fi
...
done

Ele aceitará qualquer comando, mantendo intactas as variáveis ​​locais. Para sair do modo "debug", digite "exit" (não sairá do script) e continuará com o código. Se você usar "debug" dentro de um loop, ele será interrompido a cada vez. Você pode colocá-lo dentro de um "se" (como no exemplo acima) ou criar uma função "watch":

function debug_watch
{
    if [[ $1 == $2 ]]; then
        debug
    fi
}

# And Use it:

debug_watch "$file" "strange_case.txt"

Eu também adicionei o comando "vars", que despejará todas as variáveis ​​disponíveis e seus valores. Você também pode adicionar seus próprios comandos personalizados.

Fiz o código em alguns minutos, portanto, use-o por sua conta e risco. Esteja ciente de que, no modo de depuração, qualquer comando pode ser executado; portanto, isso representa um risco de segurança se você o deixar em um script de produção.

lepe
fonte
3
Evite usar nomes de variáveis ​​em maiúsculas. Seu risco de substituir variáveis ​​especiais do shell e variáveis ​​de ambiente. Além disso, lembre-se de citar as expansões dos parâmetros quando elas são usadas como argumentos, para evitar que a expansão da divisão de nomes e do caminho ocorra no resultado. por exemplo, * ) eval "$cmd" ;;e debug_watch "$file" strange_case.txt.
Geirha 15/05
Código editado conforme sugerido por geirha.
lepe
2

Para o que o NES está dizendo, há sinalizadores definidos no bash para permitir a depuração.

O set -xsinalizador pode ser definido e desabilitado no terminal ou dentro do seu script. Usando +ou -:

#!/bin/bash
#fileinfo
ls -l $1
set -x      # start debugging here
wc -l $1
set +x      # stop debugging here
file $1
set -v      # start verbose output
w | more    
echo ""
echo -n "Number of users: "
set +v      # end verbose output
who | wc -l

Aqui está o que os setcomandos fazem:

  • set -f Desative a geração de nome de arquivo usando metacaracteres.
  • set -v Imprime linhas de entrada do shell (detalhadas) à medida que são lidas.
  • set -x Imprima rastreamentos de comandos antes de executar o comando.

setna verdade, possui muitos recursos, mas lamentavelmente nenhuma página de manual, pois é um shell integrado à ferramenta. O manual para set está na documentação do GNU Bash .

Existem inúmeras ferramentas de linha de comando que podem ajudá-lo a obter detalhes sobre o seu programa, como:

  • stat exibir arquivo ou status do sistema de arquivos
  • file determine um tipo de arquivo.
  • hexdump filtro que exibe os arquivos especificados em vários formatos
  • nohup Execute um script que não travará

    e muitos outros. Eu estava tentando pensar no comando que mostra caracteres ocultos, mas não posso fazê-lo agora. O Hexdump fará isso, mas há um melhor.

O comando key ctrl\fará com que um programa ou script em execução seja executado no core dump. Então você pode analisar o coredump. Eu provavelmente usaria o gdb para analisar um coredump, mas existem muitos programas para isso.

O shell bash também possui algumas opções bacanas para depuração. opções --debugger, -vdetalhado --dump-stringse outras opções bacanas para ajudá-lo. Vê-los usando man bash.

O trapcomando (shell incorporado) pode ser muito útil para você. trap diz que se o seu programa sair inesperadamente, execute algo. Você leu sobre armadilhas e outros práticos recursos do Bash Shell aqui .

Falando de um modo geral no momento, a depuração é um tópico enorme em qualquer idioma. Alguns outros tópicos que podem ser úteis para depuração em qualquer linguagem de programação incluem redirecionamento de shell e processamento de sinal.

Finalmente, percebo que o exemplo que usei é trivial, mas que alguns scripts de shell podem ter centenas de linhas. Nessas situações, gosto de inserir tags de comentários e bloquear o código que suspeito estar com defeito ou, alternativamente, inserir um comando de saída e tentar isolar o código funcional do código quebrado, usando uma técnica de divisão e conquista.

j0h
fonte
1

Uma opção da GUI para depurar um script bash é o IDE Eclipse com os plug-ins BashEclipse / Shelled.

Isso fornece os recursos da sua pergunta ( breakpoints and stuff), além de vários outros recursos para depurar scripts bash complexos.

Alguns dos recursos incluem:
( https://unix.stackexchange.com/questions/155551/how-to-debug-a-bash-script )

  • Alternar ponto de interrupção
  • Operação passo a passo única
  • Funções e sub-rotinas Step-in, Step-out, Step-over
  • Examinando variáveis ​​de código a qualquer momento enquanto o script está em execução
  • Lista de tarefas TODO
  • Lista de favoritos
  • Edição de várias janelas
  • Compartilhamento remoto do ambiente do projeto

A perspectiva do Editor de scripts: IDE do Eclipse Script

A perspectiva de depuração: Perspectiva de Depuração de Script Eclipse

As etapas para o uso são adicionar os plugins Shellede BashEclipseao eclipse. Em seguida, execute o procedimento fornecido no arquivo de texto leia-me do BashEclipse para iniciar o depurador.

LD James
fonte