NetSago
Вход
Войти

Как присоединиться?
Меню
Главная
События
 Заметки
Статьи
Теги
Поиск
О Проекте
Ссылки
Наше
RSS События по RSS
RSS Заметки по RSS
netsago NetSago
Популярное
Руководство по получению прибыли от Свободных и Открытых Проектов by Джон Эндрюс

Восстановление удаленных текстовых файлов в ФС ext3 by scamelscrud

Заметки — Отладка шелл-скриптов с помощью bashdb
Назад в Заметки

Отладка шелл-скриптов с помощью bashdb
n0xi0uzz



Теги: bash debug



Перевод статьи Ben Martin «Debug your shell scripts with bashdb».

Bash Debugger Project позволяет вам устанавливать точки прерывания, следить за состоянием переменных, производить бэктрейс и проходить построчно по скрипту. Другими словами, он предоставляет возможности отладчика C/C++ для тех, кто пишет bash-скрипты.

Чтобы проверить, имеет ли ваш bash поддержку bashdb, выполните следующую команду; если командная строка bashdb не запустится, тогда вам придется самостоятельно его установить:
$ bash --debugger -c "set|grep -i dbg"
...
bashdb<0>

Репрозиторий Ubuntu Intrepid содержит пакет для bashdb, но в репрозиториях openSUSE 11 или Fedora 9 нет такого соответствующего пакета. Я собрал его из исходного кода, используя версию bashdb 4.0-0.1 на 64-битной машине с Fedora 9, используя обычные команды: ./configure; make; sudo make install.

Вы можете запустить Bash Debagger с помощью выражения bash --debugger foo.sh или команды bashdb foo.sh. Рекомендован первый метод, за исключением случаев, когда переадресация ввода-вывода может привести к проблемам, его я и использовал. Вы также можете использовать bashdb через ddd или из буфера Emacs.

Синтаксис многих команд bashdb имитирует синтаксис команд gdb, отладчика GNU. Вы можете переходить в функции с помощью step, использовать next для выполнения следующей строки без вхождения в какую-либо функцию, генерировать бэктрейс с помощью bt, выйти из bashdb с помощью quit или Ctrl-D и проверять переменную с помощью print $foo. Помимо добавления символа $ перед переменными, как было указано в конце последнего предложения, существуют и другие небольшие различия, которые стоит отметить. Например, нажатие Enter на пустой строке в bashdb выполняет предыдущий шаг или следующую команду вместо выполнения предыдущей команды.

Команда print вынуждает вас указывать перед названием переменных знак доллара ($foo). Немного более коротки путь для отслеживания состояния переменных и функций — использование команды x foo, которая использует declare для вывода переменных и функций.

И bashdb, и ваш скрипт запускаются в том же шелле. Так как bash не хватает некоторых свойств пространства имен, bashdb будет включать некоторые функции и символы в глобальное пространство имен, которое ваш скрипт может достигнуть. bashdb добавляет к своим символам префикс _Dbg_, так что вы должны избегать этот префикс в ваших скриптах, чтобы избежать потенциального конфликта. Также bashdb использует несколько переменных окружения, они начинаются с префикса DBG_ и зависят от некоторых стандартных переменных окружения bash, которые начинаются с BASH_.

Чтобы проиллюстрировать использование bashdb, я написал небольшой скрипт, который принимает численное значение n и вычисляет n-ное число Фибоначчи.
#!/bin/bash

version="0.01";

fibonacci() {
n=${1:?If you want the nth fibonacci number, \
    you must supply n as the first parameter.}
    if [ $n -le 1 ]; then 
	echo $n
    else
	l=`fibonacci $((n-1))`
	r=`fibonacci $((n-2))`
	echo $((l + r))
    fi
}

for i in `seq 1 10`
do
  result=$(fibonacci $i)
  echo "i=$i result=$result"
done

Следующая сессия показывает bashdb в действии, проходя через и внутрь функции fibonacci и проверяя переменные. Я выделил вводимый мной текст полужирным для упрощения чтения. Первоначальный бэктрейс (bt) показывает, что скрипт начинается на строке 3, где описана переменная версии. Команды next и list осуществляют переход на следующую строку скрипта и показывают контекст текущей выполняемой строки. После одной команды next я нажал Enter, чтобы снова выполнить next. Я вызвал команду examine через одну букву x. Обратите внимание, что переменные выводятся с использованием declare в противоположность вывода на следующую строку с помощью print. Наконец, я установил точку прерывания в начале функции fibonacci и продолжил выполнение скрипта с помощью continue. Функция fibonacci была вызвана, и я несколько раз перешел на следующую строку с помощью next, отслеживая переменные.
$ bash --debugger ./fibonacci.sh
...
(/home/ben/testing/bashdb/fibonacci.sh:3):
3:	version="0.01";
bashdb<0> bt
->0 in file `./fibonacci.sh' at line 3
##1 main() called from file `./fibonacci.sh' at line 0
bashdb<1> next
(/home/ben/testing/bashdb/fibonacci.sh:16):
16:	for i in `seq 1 10`
bashdb<2> list
 16:==>for i in `seq 1 10`
 17:   do
 18:   result=$(fibonacci $i)
 19:   echo "i=$i result=$result"
 20:   done
bashdb<3> next
(/home/ben/testing/bashdb/fibonacci.sh:18):
18:	result=$(fibonacci $i)
bashdb<4> 
(/home/ben/testing/bashdb/fibonacci.sh:19):

        

19: echo "i=$i result=$result" bashdb<5> x i result declare -- i="1" declare -- result="" bashdb<7> print $i $result 1 bashdb<10> break fibonacci Breakpoint 1 set in file /home/ben/testing/bashdb/fibonacci.sh, line 5. bashdb<11> continue Breakpoint 1 hit (1 times). (/home/ben/testing/bashdb/fibonacci.sh:5): 5: fibonacci() { bashdb<(12)> next (/home/ben/testing/bashdb/fibonacci.sh:6): 6: n=${1:?If you want the nth fibonacci number, \ you must supply n as the first parameter.} bashdb<(13)> next (/home/ben/testing/bashdb/fibonacci.sh:7): 7: if [ $n -le 1 ]; then bashdb<(14)> x n declare -- n="2" bashdb<(15)> quit

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

В следующем примере я использую контрольную точку (watchpoint), чтобы увидеть, меняется ли переменная result, и если да, то где. Обратите внимание на первую команду next. Я обнаружил, что если я не вызову её, тогда контрольная точка не сработает. Как вы видите, после вызова c для продолжения выполнения, выполнение все равно останавливается, где бы не изменилась переменная result и отображаются её новое и старое значения.
(/home/ben/testing/bashdb/fibonacci.sh:3):
3:	version="0.01";
bashdb<0> next
(/home/ben/testing/bashdb/fibonacci.sh:16):
16:	for i in `seq 1 10`
bashdb<1> watch result
 0: ($result)==0 arith: 0
bashdb<2> c
Watchpoint 0: $result changed:
  old value: ''
  new value: '1'
(/home/ben/testing/bashdb/fibonacci.sh:19):
19:	echo "i=$i result=$result"
bashdb<3> c
i=1 result=1
i=2 result=1
Watchpoint 0: $result changed:
  old value: '1'
  new value: '2'
(/home/ben/testing/bashdb/fibonacci.sh:19):
19:	echo "i=$i result=$result"

Чтобы обойти странное требование первоначального вызова next, в следующей сессии я использовал команду watche, которая позволяет вам остановиться, где бы условие ни приняло значение true. В данном случае меня больше не интересуют первые несколько чисел Фибоначчи, так что я установил контрольную точку, чтобы выполнение остановилось, когда переменная result принимает значение больше 4. Также вы можете использовать команду watche без условия. Например, watche result остановит выполнение, где бы переменная result не изменилась.
$ bash --debugger ./fibonacci.sh
(/home/ben/testing/bashdb/fibonacci.sh:3):
3:	version="0.01";
bashdb<0> watche result > 4
 0: (result > 4)==0 arith: 1
bashdb<1> continue
i=1 result=1
i=2 result=1
i=3 result=2
i=4 result=3
Watchpoint 0: result > 4 changed:
  old value: '0'
  new value: '1'
(/home/ben/testing/bashdb/fibonacci.sh:19):
19:	echo "i=$i result=$result"

В случае ошибок при выполнении шелл-скрипта, многие используют метод добавления выражений echo или printf, чтобы увидеть некорректные значения или части кода. С помощью bashdb вы можете сохранить ваше время, просто добавив несколько контрольных точек для переменных или установкой нескольких точек прерывания.
Язык
English/Английский
Поиск
Расширенный Поиск
Ошиблись?
Если вы обнаружили ошибку на сайте, пожалуйста, сообщите нам о ней.
Посчитали
5 / 1066
К нам сегодня зашли 29 роботов. Они хотят убить всех человеков.

Зарегистрированных пользователей: 0
Онлайн: 0

Время генерации: 0.010 с
NetSago.v2.β © [2006;∞)  Neunica