Как отладить скрипт bash?

135

У меня проблемы с некоторыми скриптами в bash, по поводу ошибок и неожиданного поведения. Я хотел бы исследовать причины проблем, чтобы я мог применить исправления. Есть ли способ, которым я могу включить некий «режим отладки» для bash, чтобы получить больше информации?

Braiam
источник

Ответы:

132

Запустите скрипт bash с помощью bash -x ./script.shили добавьте его в свой скрипт, set -xчтобы увидеть результаты отладки.


Дополнительно с bash4.1 или позже:

Если вы хотите записать выходные данные отладки в отдельный файл, добавьте это в ваш скрипт:

exec 5> debug_output.txt
BASH_XTRACEFD="5"

Смотрите: https://stackoverflow.com/a/25593226/3776858


Если вы хотите увидеть номера строк, добавьте это:

PS4='$LINENO: '


Если у вас есть доступ к loggerкоманде, вы можете использовать ее для записи отладочной информации через системный журнал с отметкой времени, именем скрипта и номером строки:

#!/bin/bash

exec 5> >(logger -t $0)
BASH_XTRACEFD="5"
PS4='$LINENO: '
set -x

# Place your code here

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

Кир
источник
7
-v также может помочь (выводит каждую строку по мере их выполнения. может комбинироваться с -x). И смотрите также: bashdb.sourceforge.net
Оливье Дюлак
4
Еще один замечательный ресурс: shellcheck.net
Оливье Дюлак
Что делает "exec 5>"?
Aggsol
3
@aggsol: Если вы используете BASH_XTRACEFD="5"bash, записывает вывод трассировки, сгенерированный, когда set -xон включен, в файловый дескриптор 5. exec 5> >(logger -t $0)перенаправляет вывод из файлового дескриптора 5 в loggerкоманду.
Cyrus
1
Просто интересно, вы можете получить номер строки и путь или имя сценария оболочки в PS4?
iloveretards
55

С помощью set -x

Я всегда использую set -xи set +x. Вы можете обернуть области, которые вы хотите видеть, что происходит с ними, чтобы повернуть детализацию вверх / вниз.

#!/bin/bash

set -x
..code to debug...
set +x

log4bash

Также, если вы выполнили работу по разработке и знакомы со стилем логгеров, которые называются log4j, log4perl и т. Д., Вы можете использовать log4bash .

выдержка

Посмотрим правде в глаза - просто старое эхо просто не режет это. log4bash - это попытка улучшить ведение журнала для сценариев Bash (т. е. сделать так, чтобы вход в Bash меньше занимал).

Оттуда вы можете делать такие вещи в своих скриптах Bash:

#!/usr/bin/env bash
source log4bash.sh

log "This is regular log message... log and log_info do the same thing";

log_warning "Luke ... you turned off your targeting computer";
log_info "I have you now!";
log_success "You're all clear kid, now let's blow this thing and go home.";
log_error "One thing's for sure, we're all gonna be a lot thinner.";

# If you have figlet installed -- you'll see some big letters on the screen!
log_captains "What was in the captain's toilet?";

# If you have the "say" command (e.g. on a Mac)
log_speak "Resistance is futile";

В результате этого типа вывода:

    ss1

log4sh

Если вам нужно что-то более портативное, есть и старшее log4sh. Работы аналогичные log4bash, доступные здесь:

SLM
источник
В Ubuntu у меня есть alias say="spd-say".bashrc, который имитирует sayкоманду из других дистрибутивов или OS X.
Doorknob
1
set -vx будет хорошей комбинацией, если используется с отладкой trap - trap read. Это позволяет вам перешагивать строки за строкой и видеть результаты
Магнус Мелвин
34

Есть отладчик bash, bashdb , который устанавливается во многих дистрибутивах. Он использует встроенный расширенный режим отладки bash ( shopt -s extdebug). Это очень похоже на GDB; вот пример сеанса, чтобы придать некоторый вкус:

$ ls
1st.JPG  2ndJPG.JPG
$ cat ../foo.sh
for f in *.JPG
do
  newf=${f/JPG/jpg}
  mv $f $newf
done
$ bashdb ../foo.sh
(foo.sh:1):
1:      for f in *.JPG
bashdb<0> next
(foo.sh:3):
3:        newf=${f/JPG/jpg}
bashdb<1> next
(foo.sh:4):
4:        mv $f $newf

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

bashdb<2> print $f $newf
1st.JPG 1st.jpg
bashdb<3> next
(foo.sh:1):
1:      for f in *.JPG
bashdb<4> next
(foo.sh:3):
3:        newf=${f/JPG/jpg}
bashdb<5> next
(foo.sh:4):
4:        mv $f $newf
bashdb<6> print $f $newf
2ndJPG.JPG 2ndjpg.JPG

Это не то, что мы хотим! Давайте снова посмотрим на расширение параметров.

bashdb<7> print $f ${f/JPG/jpg}
2ndJPG.JPG 2ndjpg.JPG
bashdb<8> print $f ${f/JPG$/jpg}
2ndJPG.JPG 2ndJPG.JPG
bashdb<9> print $f ${f/%JPG/jpg}
2ndJPG.JPG 2ndJPG.jpg

ОК, это работает. Давайте установим newfправильное значение.

bashdb<10> eval newf=${f/%JPG/jpg}
$? is 0
bashdb<11> print $f $newf
2ndJPG.JPG 2ndJPG.jpg

Выглядит неплохо. Продолжите сценарий.

bashdb<12> next
Debugged program terminated normally. Use q to quit or R to restart.
$ ls
1st.jpg  2ndJPG.jpg
Марк Плотник
источник
20

Стандартный метод отладки сценариев в большинстве оболочек на основе Bourne, таких как bash, - писать set -xв верхней части сценария. Это сделает bash более подробным о том, что делается / выполняется, и как оцениваются аргументы.

-x  Print commands and their arguments as they are executed.

это полезно как для интерпретатора, так и для скриптов. Например:

$ find "$fileloc" -type f -prune "$filename" -print
+ find /var/adm/logs/morelogs -type f -prune '-name *.user' -print
find: unknown predicate '-name *.user'
$ find "$fileloc" -type f -prune $filename -print
+ find /var/adm/logs/morelogs -type f -prune -name '*.user' -print
find: '/var/adm/logs/morelogs': No such file or directory

Выше мы видим, почему поиск не работает из-за некоторых одинарных кавычек.

Чтобы отключить функцию, просто введите set +x.

Braiam
источник
13

Использование Eclipse

Вы можете использовать комбинированную среду Eclipse и Shelled с помощью скрипта "_DEBUG.sh", приведенного ниже.

Переключение оболочек

По умолчанию инструмент разработки Shelled используется /bin/dashв качестве интерпретатора. Я изменил это, чтобы /bin/bashиметь лучшую совместимость с большинством примеров оболочек в Интернете и моей средой.

ПРИМЕЧАНИЕ. Вы можете изменить это, выбрав: Окно -> Параметры -> Сценарий оболочки -> Интерпретаторы.

Инструкция по настройке

В пакете Debugger есть шаги по использованию _DEBUG.shсценария для отладки сценария, который в основном (readme.txt):

  1. Создать проект сценария оболочки: Файл -> Создать -> Другое -> Сценарий оболочки -> Мастер проекта сценария оболочки .
  2. Создайте файл сценария Bash: Файл -> Создать -> Файл . Для этого примера это будет script.sh. Расширение должно быть ".sh" и является обязательным.
  3. Скопируйте файл _DEBUG.shв папку проекта.
  4. Вставьте следующий текст в начало файла script.sh:

    . _DEBUG.sh
  5. Если файл создан в Microsoft Windows, то обязательно выполните File -> Convert Line Delimiters To -> Unix .

  6. Настройте конфигурацию запуска отладки: Run -> Debug Configurations -> Bash script ... Здесь можно установить 2 поля:

    a) «Сценарий Bash:» - путь в рабочей области Eclipse к сценарию Bash для отладки.
    e) «Порт отладчика: 33333»

  7. Переключитесь на перспективу Debug. Запустите сеанс отладки. Запустите script.shиз оболочки Bash.

Интерфейс отладки bash

введите описание изображения здесь

Этот bash-отладчик обладает всеми функциями стандартных программных отладчиков, таких как:

  • Точка останова
  • Одна пошаговая операция
  • Функции Step-in, Step-out, Step-over и подпрограммы
  • Проверка кода или переменных в любой момент во время работы скрипта

Shelled (Shell редактор сценариев) IDE (Integrated Development Environment) имеет дополнительный бонус выполнения проверки контекста, выделяя и отступов при написании сценария. Если он не имеет правильного отступа, вы можете сразу же пометить / указать много ошибок там.

Тогда есть другие преимущества IDE, такие как:

  • Список задач TODO
  • Mylyn Task
  • Список закладок
  • Редактирование нескольких окон
  • Удаленный обмен окружающей средой
Л.Д. Джеймс
источник
Классный совет. Приятно знать, что Bash можно так отлаживать.
СЛМ
8

В последние годы появился замечательный ресурс: http://shellcheck.net

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

Просто убедитесь, что вы не вставляете конфиденциальную информацию (ips, пароли и т. Д.) Через сеть ... (особенно если это http, незашифрованный) (я считаю, что shellcheck также доступен для загрузки, но я не уверен)

Оливье Дюлак
источник
6

просто используйте:

#!/bin/bash -x

то же самое для оболочки:

#!/bin/sh -x
Джери
источник
6

В настоящее время есть VS Code Bash Debug.

https://marketplace.visualstudio.com/items?itemName=rogalmic.bash-debug

Он имеет «Step in / out / over», а также показывает значение каждой переменной.

Скриншот отладки VS Code Bash

Энрике Лемос Рибейро
источник
этот ответ не относится к вопросу в правильном контексте; предполагая командную строку, так как IDE не была упомянута
qodeninja