Як налагодити скрипт bash?


135

У мене виникають проблеми з деякими сценаріями в баші, з приводу помилок і несподіваної поведінки. Я хотів би вивчити причини проблем, щоб я міг застосувати виправлення. Чи є спосіб я перетворити якийсь режим "налагодження" для bash, щоб отримати більше інформації?

Відповіді:


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команди, ви можете використовувати це для написання виводу налагодження через ваш syslog із позначкою часу, ім'ям сценарію та номером рядка:

#!/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>"?
аггсол

3
@aggsol: Якщо ви використовуєте BASH_XTRACEFD="5"bash, записуйте вихідний слід, створений при set -xвключенні файлу дескриптора 5. exec 5> >(logger -t $0)перенаправляє вихід з дескриптора 5 файлів на loggerкоманду.
Кір

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, доступні тут:


У Ubuntu у мене є alias say="spd-say".bashrc, який імітує sayкоманду з інших дистрибутивів або OS X.
Doorknob

1
set -vx була б гарною комбінацією, якщо використовується з trap - trap read debug. Це дозволяє переходити по черзі за рядком і бачити результати
Магнус Мелвін

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

Стандартний метод налагодження сценаріїв у більшості оболонок на основі Борна, як-от bash, - це писати set -xу верхній частині вашого сценарію. Це зробить грубість більш детальною щодо того, що робиться / виконується, і як оцінюються аргументи.

-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.


13

Використання Eclipse

Ви можете використовувати комбіноване середовище Eclipse та Shells за допомогою сценарію "_DEBUG.sh", який пов'язаний нижче.

Перемикання оболонок

За замовчуванням інструмент розробки Sheiled використовує /bin/dashяк інтерпретатор. Я змінив це, щоб /bin/bashмати кращу сумісність з більшістю прикладів оболонок в Інтернеті та моєму середовищі.

ПРИМІТКА. Ви можете змінити це, перейшовши до: Вікно -> Налаштування -> Сценарій оболонки -> Інтерпретатори

Інструкції з налаштування

У пакеті налагодження є кроки для використання _DEBUG.shсценарію для налагодження сценарію, який є в основному (readme.txt):

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

    . _DEBUG.sh
  5. Якщо файл створено в Microsoft Windows, тоді обов'язково виконайте файл -> Перетворити розділові лінії в -> Unix .

  6. Налаштування конфігурації запуску налагодження: Виконати -> Конфігурації налагодження -> Сценарій Bash ... Тут потрібно встановити 2 поля:

    a) "Bash script:" - Шлях у робочій області Eclipse до сценарію Bash для налагодження.
    д) "Порт налагодження:" 33333

  7. Переключіться на перспективу налагодження. Почніть сеанс налагодження. Запуск script.shіз шкаралупи bash.

Користувацький інтерфейс налагодження

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

Цей налагоджувач bash має всі функції стандартних відладчиків програмування, такі як:

  • Перемикач точки перерви
  • Покрокова операція
  • Покрокові, вихідні, перехідні функції та підпрограми
  • Вивчення коду чи змінних у будь-якій точці, поки виконується сценарій

Shelled (Shell редактор сценаріїв) IDE (Integrated Development Environment) має додатковий бонус виконання перевірки контексту, виділяючи і відступів при написанні сценарію. Якщо він не вводиться правильно, ви можете негайно позначити / локалізувати багато помилок.

Потім є інші переваги IDE, такі як:

  • Список завдань TODO
  • Завдання Милин
  • Список закладок
  • Редагування декількох вікон
  • Віддалений обмін середовищем

Класна порада. Приємно знати, що Bash можна налагодити так.
slm

8

В останні роки з’явився чудовий ресурс: http://shellcheck.net

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

Просто переконайтеся, що ви не вставляєте чутливі відомості (ips, паролі тощо) через мережу ... (особливо, якщо це http, незашифрований) (я вважаю, що також можна завантажити, але я не впевнений)


6

просто використовуйте:

#!/bin/bash -x

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

#!/bin/sh -x

6

На сьогоднішній день існує налагодження VS Code Bash.

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

Він має "Крок / вихід / перехід", а також показує значення кожної змінної.

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


ця відповідь не відповідає на питання в правильному контексті; припускаючи командний рядок, оскільки IDE не згадували
qodeninja
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.