Como depurar scripts Bash

Como depurar scripts Bash

Existem técnicas de ambientes de programação tradicionais que podem ajudar.
Algumas ferramentas básicas, como usar um editor com destaque de sintaxe, também ajudarão.
Existem opções incorporadas que o Bash oferece para facilitar a depuração e seu trabalho diário de administração do sistema Linux.

Neste artigo, você aprenderá alguns métodos úteis para depurar scripts de bash:

  • Como usar técnicas traditosnais
  • Como usar a opção XTRACE
  • Como usar outras opções de festa
  • Como usar a armadilha

A ferramenta de depuração mais eficaz ainda é cuidadosa, juntamente com declarações de impressão criteriosamente colocadas. - Brian Kernighan, "Unix for Beginners" (1979)

Requisitos de software e convenções usadas

Requisitos de software e convenções de linha de comando Linux
Categoria Requisitos, convenções ou versão de software usada
Sistema Qualquer distribuição GNU/Linux
Programas GNU Bash
Outro N / D
Convenções # - requer que os comandos Linux sejam executados com privilégios root diretamente como usuário root ou por uso de sudo comando
$ - Requer que os comandos do Linux sejam executados como um usuário não privilegiado regular

Usando técnicas tradicionais

O código de depuração pode ser complicado, mesmo que os erros sejam simples e óbvios. Os programadores tradicionalmente aproveitam ferramentas como depuradores e destaques de sintaxe nos editores para ajudá -los. Não é diferente ao escrever scripts de basquete. Simplesmente ter o destaque da sintaxe permitirá que você pegue erros enquanto escreva o código, economizando a tarefa demorada de rastrear erros mais tarde.

Algumas linguagens de programação vêm com ambientes de depuração complementares, como GCC e GDB que permitem passar pelo código, definir pontos de interrupção, examinar o estado de tudo nesses pontos da execução e mais - mas geralmente há menos necessidade de uma abordagem pesada como essa com com a scripts de shell, pois o código é simplesmente interpretado em vez de ser compilado em binários.

Existem técnicas usadas em ambientes de programação tradicionais que podem ser úteis com scripts de bash complexos, como o uso de afirmações. Essas são basicamente uma maneira de afirmar explicitamente condições ou o estado das coisas em um momento. Asserções podem identificar até o mais sutil dos bugs. Eles podem ser implementados como uma função curta que mostra o tempo, o número da linha e tal, ou algo assim:

$ echo "function_name (): valor de \\ $ var é $ var"

Como usar a opção Bash Xtrace

Ao escrever scripts de shell, a lógica de programação tende a ser mais curta e geralmente está contida em um único arquivo. Portanto, existem algumas opções de depuração embutidas que podemos usar para ver o que está dando errado. A primeira opção a mencionar é provavelmente a mais útil também - o xtrace opção. Isso pode ser aplicado a um script, invocando o Bash com o -x trocar.

$ Bash -x 


Isso diz ao BASH para nos mostrar como é cada declaração após a avaliação, pouco antes de ser executada. Veremos um exemplo disso em ação em breve, mas primeiro vamos contrastar -x com seu oposto -v, que mostra cada linha antes de ser avaliada em vez de depois. As opções podem ser combinadas e usando os dois -x e -v Você pode ver como são as declarações antes e depois que as substituições variáveis ​​ocorrem.

Contexto x e v Opções na linha de comando

Observe como o uso -x e -v As opções juntas nos permitem ver a instrução IF original antes do $ Usuário A variável é expandida, graças ao -v opção. Também vemos na linha começando com um sinal positivo como é a afirmação novamente após a substituição, o que nos mostra os valores reais comparados dentro do se declaração. Em exemplos mais complicados, isso pode ser bastante útil.

Como usar outras opções de festa

As opções de bash para depuração são desligadas por padrão, mas uma vez que elas são ativadas usando o comando set, eles permanecem até explicitamente desligados. Se você não tiver certeza de quais opções estão ativadas, você pode examinar o $- variável para ver o estado atual de todas as variáveis.

$ echo $- HIMBHS $ set -XV && echo $- HIMVXBHS 

Há outro interruptor útil que podemos usar para nos ajudar a encontrar variáveis ​​referenciadas sem ter nenhum valor definido. Isto é o -você mudar, e exatamente como -x e -v Também pode ser usado na linha de comando, como vemos no exemplo a seguir:

Contexto você opção na linha de comando

Nós, por engano, atribuímos um valor de 7 à variável chamada "nível" e tentamos ecoar uma variável chamada "Score" que simplesmente resultou em imprimir nada na tela. Absolutamente nenhuma informação de depuração foi dada. Definindo nosso -você Switch nos permite ver uma mensagem de erro específica, “Score: Unbound Variable” que indica exatamente o que deu errado.

Podemos usar essas opções em scripts curtos de bash para nos fornecer informações de depuração para identificar problemas que, de outra forma, não desencadeiam feedback do intérprete da festa. Vamos passar por alguns exemplos.

#!/bin/bash leia -p "caminho a ser adicionado:" $ caminho se ["$ path" = "/home/mike/bin"]; Então echo $ path >> $ PATH ECHO "NOVO PATH: $ PATH" else Echo "não modificou o caminho" FI 
cópia de Usando x opção ao executar seu script de bash

No exemplo acima, executamos o script de add path normalmente e ele simplesmente não modifica nosso CAMINHO. Não nos dá nenhuma indicação de por que ou pistas para erros cometidos. Executando novamente usando o -x A opção mostra claramente que o lado esquerdo da nossa comparação é uma corda vazia. $ caminho é uma corda vazia porque acidentalmente colocamos um sinal de dólar na frente de "Path" em nossa declaração de leitura. Às vezes olhamos para um erro como esse e não parece errado até conseguirmos uma pista e pensarmos: "Por que é $ caminho avaliado em uma corda vazia?”

Olhando o próximo exemplo, também não temos indicação de um erro do intérprete. Temos apenas um valor impresso por linha em vez de dois. Este não é um erro que interromperá a execução do script, então ficamos simplesmente imaginando sem receber nenhuma pista. Usando o -você Switch, recebemos imediatamente uma notificação de que nossa variável j não está vinculado a um valor. Portanto, esses são poupadores em tempo real quando cometemos erros que não resultam em erros reais do ponto de vista do intérprete.

#!/BIN/BASH para i em 1 2 3 do eco $ i $ J feito 
cópia de Usando você opção executando seu script na linha de comando

Agora, certamente você está pensando que parece bem, mas raramente precisamos de ajuda para depurar erros cometidos em uma linha na linha de comando ou em scripts curtos como esses. Normalmente, lutamos para depurar quando lidamos com scripts mais longos e complicados, e raramente precisamos definir essas opções e deixá -las definidas enquanto executamos vários scripts. Contexto -xv Opções e, em seguida, executando um script mais complexo geralmente adiciona confusão dobrando ou triplicando a quantidade de saída gerada.

Felizmente, podemos usar essas opções de uma maneira mais precisa, colocando -as dentro de nossos scripts. Em vez de invocar explicitamente um shell bash com uma opção da linha de comando, podemos definir uma opção adicionando -a à linha Shebang em vez.

#!/bin/bash -x

Isso definirá o -x Opção para o arquivo inteiro ou até que não esteja definido durante a execução do script, permitindo que você simplesmente execute o script digitando o nome do arquivo em vez de passá -lo para Bash como um parâmetro. Um script longo ou que possui muita saída ainda se tornará pesado usando essa técnica, então, vejamos uma maneira mais específica de usar opções.



Para uma abordagem mais direcionada, envolva apenas os blocos suspeitos de código com as opções que você deseja. Essa abordagem é ótima para scripts que geram menus ou saída detalhada e é realizada usando a palavra -chave definida com mais ou menos mais uma vez.

#!/BIN/BASH READ -P "Caminho a ser adicionado:" $ SET PATH -XV IF ["$ PATH" = "/Home/Mike/Bin"]; Então echo $ path >> $ path eco "novo caminho: $ path" else eco "não modificou o caminho" fi set +xv 
cópia de Opções de embrulho em torno de um bloco de código em seu script

Recebemos apenas os blocos de código que suspeitamos para reduzir a saída, facilitando nossa tarefa no processo. Observe que ativamos nossas opções apenas para o bloco de código que contém nossa instrução if-then-else e depois desligue as opções no final do bloco suspeito. Podemos ativar e desativar essas opções várias vezes em um único script se não pudermos restringir as áreas suspeitas ou se queremos avaliar o estado de variáveis ​​em vários pontos à medida que progredimos através do script. Não há necessidade de desligar uma opção se quiser que ela continue pelo restante da execução do script.

Por uma questão de completude, devemos mencionar também que existem depuradores escritos por terceiros que nos permitirão passar pela execução do código linha por linha. Você pode querer investigar essas ferramentas, mas a maioria das pessoas acha que elas não são realmente necessárias.

Como os programadores experientes sugerem, se seu código for muito complexo para isolar blocos suspeitos com essas opções, o verdadeiro problema é que o código deve ser refatorado. Código excessivamente complexo significa que os bugs podem ser difíceis de detectar e a manutenção pode ser demorada e cara.

Uma coisa final a mencionar sobre as opções de depuração do Bash é que uma opção de globbing de arquivos também existe e está definida com -f. A configuração desta opção desativará o globbing (expansão de curingas para gerar nomes de arquivos) enquanto estiver ativado. Esse -f A opção pode ser uma chave usada na linha de comando com Bash, após a shebang em um arquivo ou, como neste exemplo para cercar um bloco de código.

#!/bin/bash eco "Ignore FileGlobbing Option Desligou desligado" ls * echo "Ignore File Globbing Option Set" Set -f ls * set +f 
cópia de Usando f Opção para desativar o Globbing de Arquivos

Como usar a armadilha para ajudar a depurar

Existem mais técnicas envolvidas que vale a pena considerar se seus scripts são complicados, incluindo o uso de uma função assert, conforme mencionado anteriormente. Um desses métodos a serem lembrados é o uso da armadilha. Scripts de shell nos permitem prender sinais e fazer algo naquele momento.

Um exemplo simples, mas útil, que você pode usar em seus scripts bash é prender SAÍDA.

#!/Bin/Bash Trap 'Echo Score é $ pontuação, status é $ status' saída se [-z $ 1]; então status = "padrão" else Status = $ 1 fi pontuação = 0 se [$ user = 'Superman']; então pontuação = 99 elif [$# -gt 1]; então pontuação = $ 2 fi 
cópia de Usando trap SAÍDA Para ajudar a depurar seu script

Como você pode ver, apenas despejar os valores atuais das variáveis ​​na tela pode ser útil para mostrar onde sua lógica está falhando. O SAÍDA o sinal obviamente não precisa de um explícito saída declaração a ser gerada; neste caso o eco A declaração é executada quando o final do script é alcançado.

Outra armadilha útil para usar com scripts de bash é DEPURAR. Isso acontece após cada afirmação, para que possa ser usado como uma maneira de força bruta de mostrar os valores das variáveis ​​em cada etapa da execução do script.

#!/bin/bash trap 'echo "linha $ lineno: pontuação é $ pontuação"' escore de depuração = 0 se ["$ user" = "mike"]; Então, deixe "pontuar += 1" fi deixar "pontuar += 1" se ["$ 1" = "7"]; então pontuação = 7 fi saída 0 
cópia de Usando trap DEPURAR Para ajudar a depurar seu script

Conclusão

Quando você percebe que seu script bash não se comporta como o esperado e o motivo não é claro para você por qualquer motivo, considere quais informações seriam úteis para ajudá -lo a identificar a causa e use as ferramentas mais confortáveis ​​disponíveis para ajudá -lo a identificar o problema. A opção xtrace -x é fácil de usar e provavelmente o mais útil das opções apresentadas aqui, então considere experimentá -lo na próxima vez que você se deparar com um script que não está fazendo o que você pensou.

Tutoriais do Linux relacionados:

  • Como propagar um sinal para os processos filhos de uma festa…
  • Mastering Bash Script Loops
  • Como executar operações de administração com Ansible…
  • Loops aninhados em scripts de basquete
  • Como usar as sub -mais de bases dentro das declarações if if
  • Uma introdução à automação, ferramentas e técnicas do Linux
  • Coisas para instalar no Ubuntu 20.04
  • Como usar o ADB Android Debug Bridge para gerenciar seu Android…
  • Bash If Declarações: Se, Elif, caso contrário, então, FI
  • Otimização de desempenho do Linux: ferramentas e técnicas