Depuração de um script Bash

visão geral

neste tutorial, vamos olhar para as várias técnicas para depurar scripts Bash shell. A Bash shell não fornece nenhum depurador incorporado. No entanto, existem certos comandos e construções que podem ser utilizados para este propósito.

Primeiro, vamos discutir as utilizações do comando set para depuração de scripts. Depois disso, vamos verificar alguns casos de uso específicos de depuração usando os comandos set e trap. Finalmente, vamos apresentar alguns métodos para depurar scripts já em execução.

Bash Debugging Options

the debugging options available in the Bash shell can be Shell on and off in multiple ways. Dentro dos scripts, podemos usar o comando set ou adicionar uma opção à linha shebang. No entanto, outra abordagem é especificar explicitamente as opções de depuração na linha de comandos ao executar o script. Vamos mergulhar na discussão.

2.1. Activar o modo descritivo

podemos activar o modo descritivo usando o interruptor-v, que nos permite ver cada comando antes de ser executado.

para demonstrar isso, vamos criar um script de amostra:

#! /bin/bashread -p "Enter the input: " valzero_val=0if then echo "Positive number entered."else echo "The input value is not positive."fi

este programa verifica se o número introduzido como entrada é positivo ou não.A seguir, vamos executar o nosso script:

$ bash -v ./positive_check.sh#! /bin/bashread -p "Enter the input: " valEnter the input: -10zero_val=0if then echo "Positive number entered."else echo "The input value is not positive."fiThe input value is not positive.

como podemos notar, imprime todas as linhas do script no terminal antes de ser processado.

podemos também adicionar a opção-v na linha shebang:

#! /bin/bash -v

isto tem o mesmo efeito que chamar explicitamente um script usando bash-v. outro equivalente é permitir o modo dentro de um script usando o comando set:

#! /bin/bashset -v

na verdade, podemos usar qualquer uma das maneiras discutidas acima para permitir os vários switches que vamos discutir a partir de agora.

2.2. Verificação de sintaxe usando o modo noexec

pode haver situações em que podemos querer validar o script sintaticamente antes de sua execução. Se assim for, podemos usar o modo noexec usando a opção-n. Como resultado, Bash vai ler os comandos, mas não executá-los.Vamos executar o nosso positive_check.sh programa no modo noexec:

$ bash -n ./positive_check.sh

isto produz uma saída em branco uma vez que não há erros de sintaxe. Agora, vamos modificar um pouco o nosso script e remover a declaração de então:

#! /bin/bashread -p "Enter the input: " valzero_val=0if echo "Positive number entered."else echo "The input value is not positive."fi

a seguir, vamos validá-lo sintaticamente com a opção-n:

$ bash -n ./positive_check_noexec.sh./positive_check_noexec.sh: line 6: syntax error near unexpected token `else'./positive_check_noexec.sh: line 6: ` else'

como esperado, ele lançou um erro, uma vez que perdemos a declaração em seguida, na condição if.

2.3. Depuração usando o modo xtrace

na seção anterior, testamos o script para erros de sintaxe. Mas para identificar erros lógicos, podemos querer rastrear o estado das variáveis e comandos durante o processo de execução. Em tais casos, podemos executar o script no modo xtrace (execution trace) usando a opção-X.

este modo imprime o traço de comandos para cada linha após serem expandidos, mas antes de serem executados.Vamos executar o nosso positive_check.sh script no modo de traceamento da execução:

$ bash -x ./positive_check.sh+ read -p 'Enter the input: ' valEnter the input: 17+ zero_val=0+ ''+ echo 'Positive number entered.'Positive number entered.

Aqui podemos ver a versão expandida das variáveis no stdout antes da execução. É importante notar que as linhas precedidas por sinal + são geradas pelo modo xtrace.

2.4. Identificando variáveis desactivadas

vamos executar um experimento para entender o comportamento padrão das variáveis desactivadas nos scripts Bash:

#! /bin/bashfive_val=5two_val=2total=$((five_val+tow_val))echo $total

vamos agora executar o script acima:

$ ./add_values.sh5

como podemos notar, há um problema: o script executado com sucesso, mas a saída é logicamente incorreta.

vamos agora executar o script com a opção-u:

$ bash -u ./add_values.sh./add_values.sh: line 4: tow_val: unbound variable

certamente, há muito mais clareza agora!

o programa não foi executado, uma vez que a variável tow_val não está definida. Nós erroneamente digitamos two_val como tow_val ao calcular o total.

a opção-u trata variáveis e parâmetros não definidos como um erro ao executar a expansão do parâmetro. Consequentemente, recebemos uma notificação de erro de que uma variável não está vinculada ao valor ao executar o script com opção-u

usar casos para depurar Scripts Shell

até agora, vimos os vários switches para depuração scripts. A partir de agora, vamos olhar para alguns casos de uso e métodos para implementá-los em scripts shell.

3.1. Combinando opções de depuração

para obter melhores insights, podemos combinar ainda mais as várias opções do comando set.Vamos executar o nosso add_values.sh programa com ambas as opções-v e-u activadas:

$ bash -uv ./add_values.sh#! /bin/bashfive_val=5two_val=2total=$((five_val+tow_val))./add_values.sh: line 4: tow_val: unbound variable

aqui, ao habilitar o modo descritivo com a opção-u, poderíamos facilmente identificar a declaração que desencadeia o erro.Da mesma forma, podemos combinar o modo descritivo e xtrace para obter informações mais precisas de depuração.

como discutido anteriormente, a opção-v mostra cada linha antes de ser avaliada, e a opção-x mostra cada linha depois de serem expandidas. Assim, podemos combinar ambas as opções-x e-v para ver como as declarações se parecem antes e depois de substituições de variáveis.Agora, vamos executar o nosso positive_check.sh programa com o modo-x e-v activo:

$ bash -xv ./positive_check.sh#! /bin/bashread -p "Enter the input: " val+ read -p 'Enter the input: ' valEnter the input: 5zero_val=0+ zero_val=0if then echo "Positive number entered."else echo "The input value is not positive."fi+ ''+ echo 'Positive number entered.'Positive number entered.

podemos observar que as afirmações são impressas em stdout antes e depois da expansão variável.

3.2. Depuração partes específicas do Script

depuração com opções shell-X ou-v gera um resultado para cada declaração em stdout. No entanto, pode haver situações em que podemos querer reduzir a informação de depuração para apenas partes específicas do script. Nós podemos conseguir isso, ativando o modo de depuração antes do bloco de código Iniciar, e mais tarde reiniciá-lo usando o comando set.

vamos verificar com um exemplo:

#! /bin/bashread -p "Enter the input: " valzero_val=0set -xif then echo "Positive number entered."else echo "The input value is not positive."fiset +xecho "Script Ended" 

Aqui, nós poderíamos depurar apenas a condição if usando a declaração set antes do início da condição. Mais tarde, poderíamos reiniciar o modo xtrace após o fim do bloco if usando o comando set +X.

vamos validá-lo com a saída:

$ ./positive_debug.shEnter the input: 7+ ''+ echo 'Positive number entered.'Positive number entered.+ set +xScript Ended

certamente, a saída parece menos desorganizada.

3.3. Redirecionando apenas a saída de depuração para um arquivo

na seção anterior, examinamos como podemos restringir a depuração a apenas certas partes do script. Consequentemente, poderíamos restringir a quantidade de produção em stdout.

além disso, podemos redirecionar a informação de depuração para outro arquivo e deixar a saída do script imprimir no stdout.

vamos criar outro script para verificá-lo:

#! /bin/bashexec 5> debug.log PS4='$LINENO: ' BASH_XTRACEFD="5" read -p "Enter the input: " valzero_val=0if then echo "Positive number entered."else echo "The input value is not positive."fi

primeiro, abrimos a depuração.registar o ficheiro no descritor de ficheiro (FD) 5 para escrita com o comando exec.

depois mudamos a variável especial Shell PS4. A variável PS4 define a linha de comandos que é mostrada quando executamos um script shell no modo xtrace. O valor padrão de PS4 é +. Alterámos o valor da variável PS4 para mostrar os números de linha na linha de comando de depuração. Para isso, usamos outra variável shell especial LINENO.Mais tarde, Atribuímos o FD 5 à variável Bash_xtracefd. Com efeito, Bash irá agora escrever o resultado do xtrace no FD5, ou seja, debug.log. Vamos executar o script:

$ bash -x ./debug_logging.sh+ exec+ PS4='$LINENO: '4: BASH_XTRACEFD=5Enter the input: 2Positive number entered.

como esperado, o resultado de depuração não é gravado no terminal. Embora, as primeiras linhas, até que Fd 5 é atribuído à saída de depuração foram impressas.

adicionalmente, o programa também cria uma depuração de ficheiros de saída.registo, que contém a informação de depuração:

$ cat debug.log5: read -p 'Enter the input: ' val6: zero_val=07: ''9: echo 'Positive number entered.'

depurar Scripts usando trap

podemos utilizar a funcionalidade DEPUG trap de Bash para executar um comando repetitivamente. O comando especificado nos argumentos do comando trap é executado antes de cada declaração subsequente no script.Vamos ilustrar isto com um exemplo .:

#! /bin/bashtrap 'echo "Line- ${LINENO}: five_val=${five_val}, two_val=${two_val}, total=${total}" ' DEBUGfive_val=5two_val=2total=$((five_val+two_val))echo "Total is: $total"total=0 && echo "Resetting Total"

neste exemplo, especificamos o comando echo para imprimir os valores das variáveis five_val, two_val e total. Posteriormente, passamos esta declaração echo para o comando trap com o sinal de depuração. Com efeito, antes da execução de cada comando no script, os valores das variáveis são impressos.

vamos verificar a saída gerada:

$ ./trap_debug.shLine- 3: five_val=, two_val=, total=Line- 4: five_val=5, two_val=, total=Line- 5: five_val=5, two_val=2, total=Line- 6: five_val=5, two_val=2, total=7Total is: 7Line- 7: five_val=5, two_val=2, total=7Line- 7: five_val=5, two_val=2, total=0Resetting Total

depurar Scripts já em execução

até agora, nós apresentamos métodos para depurar scripts shell ao executá-los. Agora, vamos ver maneiras de depurar um script já em execução.

considere um programa de execução de amostras que executa o sono num ciclo infinito:

#! /bin/bashwhile :do sleep 10 & echo "Sleeping for 4 seconds.." sleep 4done

com a ajuda do comando pstree, podemos verificar os processos de criança bifurcados pelo nosso script sleep.sh:

$ pstree -pinit(1)─┬─init(148)───bash(149)───sleep.sh(372)─┬─sleep(422) │ ├─sleep(424) │ └─sleep(425) ├─init(213)───bash(214)───pstree(426) └─{init}(7)

usámos uma opção-p adicional para imprimir os ids do processo juntamente com os nomes do processo. Assim, somos capazes de perceber que o script está esperando que o processo infantil (sono) para completar.Por vezes, podemos querer ver mais de perto as operações realizadas pelos nossos processos. Em tais casos, podemos usar o comando strace para rastrear o sistema Linux chamadas em andamento:

$ sudo strace -c -fp 372strace: Process 372 attachedstrace: Process 789 attachedstrace: Process 790 attached^Cstrace: Process 372 detachedstrace: Process 789 detachedstrace: Process 790 detached% time seconds usecs/call calls errors syscall------ ----------- ----------- --------- --------- ----------------100.00 0.015625 5208 3 wait4 0.00 0.000000 0 6 read 0.00 0.000000 0 1 write 0.00 0.000000 0 39 close 0.00 0.000000 0 36 fstat 0.00 0.000000 0 38 mmap 0.00 0.000000 0 8 mprotect 0.00 0.000000 0 2 munmap 0.00 0.000000 0 6 brk 0.00 0.000000 0 16 rt_sigaction 0.00 0.000000 0 20 rt_sigprocmask 0.00 0.000000 0 1 rt_sigreturn 0.00 0.000000 0 6 6 access 0.00 0.000000 0 1 dup2 0.00 0.000000 0 2 getpid 0.00 0.000000 0 2 clone 0.00 0.000000 0 2 execve 0.00 0.000000 0 2 arch_prctl 0.00 0.000000 0 37 openat------ ----------- ----------- --------- --------- ----------------100.00 0.015625 228 6 total

Aqui usamos a opção -p para anexar ao processo de identificação (372) i.e. o nosso script em execução. Além disso, também usamos a opção-f para anexar a todos os seus processos filhos. Note que, o comando strace gera saída para cada chamada de Sistema. Assim, usamos a opção-c para imprimir um resumo das chamadas do sistema no término do strace.

Conclusion

In this tutorial, we studied multiple techniques to debug a shell script.

no início, discutimos as várias opções do comando set e seu uso para depuração scripts. Depois disso, implementamos vários estudos de caso para estudar uma combinação de opções de depuração. Ao lado disso, também exploramos formas de restringir a saída de depuração e redirecioná-la para outro arquivo.Em seguida, apresentamos um caso de Uso do comando trap e sinal de depuração para cenários de depuração. Finalmente, oferecemos algumas abordagens para depurar já executando scripts.

Deixe uma resposta

O seu endereço de email não será publicado.

Previous post Manny Pacquiao começou a praticar boxe aos 12 anos de idade porque até mesmo os perdedores foram pagos
Next post Birds Eye View Photography Tips