Поиск по сайту:

Как отслеживать выполнение команд в сценарии оболочки с помощью трассировки оболочки


В этой статье серии об отладке сценариев оболочки мы объясним третий режим отладки сценариев оболочки, то есть трассировку оболочки, и рассмотрим несколько примеров, демонстрирующих, как он работает и как его можно использовать.

Предыдущая часть этой серии ясно проливает свет на два других режима отладки сценариев оболочки: режим подробного описания и режим проверки синтаксиса с простыми для понимания примерами того, как включить оболочку. отладка скриптов в этих режимах.

  1. Как включить режим отладки сценариев оболочки в Linux — часть 1
  2. Как выполнить проверку синтаксиса в режиме отладки в сценариях оболочки — часть 2

Трассировка оболочки означает просто отслеживание выполнения команд в сценарии оболочки. Чтобы включить трассировку оболочки, используйте параметр отладки -x.

Это предписывает оболочке отображать все команды и их аргументы на терминале по мере их выполнения.

Ниже мы будем использовать сценарий оболочки sys_info.sh, который кратко выводит дату и время вашей системы, количество вошедших в систему пользователей и время работы системы. Однако он содержит синтаксические ошибки, которые нам необходимо найти и исправить.

#!/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

Сохраните файл и сделайте скрипт исполняемым. Сценарий может быть запущен только пользователем root, поэтому для его запуска используйте команду sudo, как показано ниже:

chmod +x sys_info.sh
sudo bash -x sys_info.sh

Из приведенного выше вывода мы можем видеть, что команда сначала выполняется, прежде чем ее вывод подставляется в качестве значения переменной.

Например, сначала была выполнена дата, а ее выходные данные были заменены значением переменной DATE.

Мы можем выполнить проверку синтаксиса, чтобы отображать только синтаксические ошибки следующим образом:

sudo bash -n sys_info.sh 

Если мы критически посмотрим на сценарий оболочки, мы поймем, что в if операторе отсутствует закрывающее слово fi. Поэтому давайте добавим его, и теперь новый скрипт должен выглядеть так, как показано ниже:

#!/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

Сохраните файл еще раз, вызовите его от имени пользователя root и выполните некоторую проверку синтаксиса:

sudo bash -n sys_info.sh

Результат нашей операции проверки синтаксиса, приведенной выше, по-прежнему показывает, что в нашем скрипте есть еще одна ошибка в строке 21. Итак, нам еще предстоит внести некоторые исправления в синтаксис.

Если мы просмотрим сценарий еще раз аналитически, ошибка в строке 21 связана с отсутствием закрывающей двойной кавычки ( ) в последней команде echo внутри . >print_sys_info.

Мы добавим закрывающую двойную кавычку в команду echo и сохраним файл. Измененный скрипт приведен ниже:

#!/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

Теперь синтаксически проверьте скрипт еще раз.

sudo bash -n sys_info.sh

Приведенная выше команда не выдаст никакого вывода, поскольку наш скрипт теперь синтаксически корректен. Мы также можем проследить выполнение скрипта во второй раз, и он должен работать хорошо:

sudo bash -x sys_info.sh

Теперь запустите скрипт.

sudo ./sys_info.sh

Важность отслеживания выполнения сценариев оболочки

Трассировка сценариев оболочки помогает нам выявлять синтаксические и, что более важно, логические ошибки. Возьмем, к примеру, функцию check_root в сценарии оболочки sys_info.sh, которая предназначена для определения того, является ли пользователь пользователем root или нет, поскольку разрешено только выполнение сценария. суперпользователем.

check_root(){
    if [ "$UID" -ne "$ROOT_ID" ]; then
        echo "You are not allowed to execute this program!"
        exit 1;
    fi
}

Магия здесь контролируется выражением if оператор [ "$UID" -ne "$ROOT_ID" ], если мы не используем подходящий числовой оператор ( -ne в данном случае, что означает не равно), мы получаем возможную логическую ошибку.

Если предположить, что мы использовали -eq (означает «равно»), это позволит любому системному пользователю, а также пользователю root запустить сценарий, что приведет к логической ошибке.

check_root(){
    if [ "$UID" -eq "$ROOT_ID" ]; then
        echo "You are not allowed to execute this program!"
        exit 1;
    fi
}

Примечание. Как мы уже говорили в начале этой серии статей, встроенная команда set оболочки может активировать отладку в определенном разделе сценария оболочки.

Поэтому строка ниже поможет нам найти эту логическую ошибку в функции, проследив ее выполнение:

Скрипт с логической ошибкой:

#!/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

Сохраните файл и вызовите скрипт. Мы увидим, что обычный пользователь системы может запустить скрипт без sudo, как показано в выводе ниже. Это связано с тем, что значение USER_ID равно 100 и не равно корневому ROOT_ID, равному 0.

./sys_info.sh

Ну, вот и все, мы подошли к концу серии статей по отладке сценариев оболочки, форму ответа ниже можно использовать для ответа на любые вопросы или отзывы, касающиеся этого руководства или всей серии из трех частей.