Como rastrear a execução de comandos em Shell Script com Shell Tracing
Neste artigo da série de depuração de shell script, explicaremos o terceiro modo de depuração de shell script, que é o rastreamento de shell, e veremos alguns exemplos para demonstrar como ele funciona e como pode ser usado.
A parte anterior desta série esclarece claramente os outros dois modos de depuração de script de shell: modo detalhado e modo de verificação de sintaxe com exemplos fáceis de entender de como ativar o shell depuração de script nesses modos.
- Como ativar o modo de depuração de Shell Script no Linux – Parte 1
- Como executar o modo de depuração de verificação de sintaxe em scripts Shell – Parte 2
Rastreamento de shell significa simplesmente rastrear a execução dos comandos em um script de shell. Para ativar o rastreamento de shell, use a opção de depuração -x
.
Isso direciona o shell para exibir todos os comandos e seus argumentos no terminal à medida que são executados.
Usaremos o script de shell sys_info.sh
abaixo, que imprime brevemente a data e hora do sistema, o número de usuários logados e o tempo de atividade do sistema. No entanto, contém erros de sintaxe que precisamos encontrar e corrigir.
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME
}
check_root
print_sys_info
exit 0
Salve o arquivo e torne o script executável. O script só pode ser executado pelo root, portanto, use o comando sudo para executá-lo conforme abaixo:
chmod +x sys_info.sh
sudo bash -x sys_info.sh
Pela saída acima, podemos observar que um comando é executado primeiro antes de sua saída ser substituída como o valor de uma variável.
Por exemplo, a data foi executada primeiro e sua saída foi substituída pelo valor da variável DATA.
Podemos realizar a verificação de sintaxe para exibir apenas os erros de sintaxe da seguinte forma:
sudo bash -n sys_info.sh
Se olharmos criticamente para o shell script, perceberemos que a instrução if
está faltando uma palavra fi
de fechamento. Portanto, vamos adicioná-lo e o novo script deve ficar como abaixo:
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME
}
check_root
print_sys_info
exit 0
Salve o arquivo novamente e invoque-o como root e faça algumas verificações de sintaxe:
sudo bash -n sys_info.sh
O resultado da nossa operação de verificação de sintaxe acima ainda mostra que há mais um bug em nosso script na linha 21. Portanto, ainda temos algumas correções de sintaxe a fazer.
Se examinarmos o script analiticamente mais uma vez, o erro na linha 21 é devido à falta de aspas duplas de fechamento ( ”)
no último comando echo dentro do print_sys_info
.
Adicionaremos as aspas duplas de fechamento no comando echo e salvaremos o arquivo. O script alterado está abaixo:
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME"
}
check_root
print_sys_info
exit 0
Agora verifique sintaticamente o script mais uma vez.
sudo bash -n sys_info.sh
O comando acima não produzirá nenhuma saída porque nosso script agora está sintaticamente correto. Também podemos rastrear a execução do script pela segunda vez e deve funcionar bem:
sudo bash -x sys_info.sh
Agora execute o script.
sudo ./sys_info.sh
Importância do rastreamento de execução do Shell Script
O rastreamento de script de shell nos ajuda a identificar erros de sintaxe e, mais importante, erros lógicos. Tomemos por exemplo a função check_root
no shell script sys_info.sh
, que tem como objetivo determinar se um usuário é root ou não, já que o script só pode ser executado pelo superusuário.
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
A mágica aqui é controlada pela expressão if statement
[ "$UID" -ne "$ROOT_ID" ]
, uma vez que não utilizamos o operador numérico adequado ( -ne
neste caso, o que significa diferente), acabamos com um possível erro lógico.
Supondo que usamos -eq
(significa igual a), isso permitiria que qualquer usuário do sistema, bem como o usuário root, executasse o script, portanto, um erro lógico.
check_root(){
if [ "$UID" -eq "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
Nota: Como vimos antes no início desta série, o comando interno set shell pode ativar a depuração em uma seção específica de um script de shell.
Portanto, a linha abaixo nos ajudará a encontrar esse erro lógico na função rastreando sua execução:
O script com um erro lógico:
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -eq "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME"
}
#turning on and off debugging of check_root function
set -x ; check_root; set +x ;
print_sys_info
exit 0
Salve o arquivo e invoque o script, podemos ver que um usuário normal do sistema pode executar o script sem sudo como na saída abaixo. Isso ocorre porque o valor de USER_ID é 100, que não é igual ao ROOT_ID raiz, que é 0.
./sys_info.sh
Bem, por enquanto é isso, chegamos ao final da série de depuração de scripts de shell, o formulário de resposta abaixo pode ser usado para responder a qualquer dúvida ou feedback para nós, em relação a este guia ou a toda a série de 3 partes.