Чи є спосіб налагодити скрипт bash? Наприклад, щось, що друкує такий собі журнал виконання, як "виклик рядка 1", "лінія виклику 2" тощо.
Чи є спосіб налагодити скрипт bash? Наприклад, щось, що друкує такий собі журнал виконання, як "виклик рядка 1", "лінія виклику 2" тощо.
Відповіді:
sh -x script [arg1 ...]
bash -x script [arg1 ...]
Вони дають вам слід про те, що виконується. (Див. Також "Роз'яснення" внизу відповіді.)
Іноді вам потрібно контролювати налагодження в сценарії. У такому випадку, як нагадав мені Cheeto , ви можете використовувати:
set -x
Це вмикає налагодження. Потім ви можете вимкнути його знову за допомогою:
set +x
(Ви можете дізнатися поточний стан відстеження, проаналізувавши $-поточні прапори для x.)
Також оболонки, як правило, надають параметри " -n" для "без виконання" та -v"для" багатослівного "режиму; Ви можете використовувати їх у поєднанні, щоб побачити, чи думає оболонка, що вона може виконати ваш сценарій - іноді корисно, якщо десь є незбалансована цитата
Існує думка, що -xваріант ' ' у Bash відрізняється від інших оболонок (див. Коментарі). Керівництво Bash каже:
-х
Роздрукуйте слід простих команд, forкоманд, caseкоманд, selectкоманд та арифметичних forкоманд та їхніх аргументів або пов'язаних списків слів після їх розширення та перед їх виконанням. Значення PS4змінної розширюється, а отримане значення друкується перед командою та її розширеними аргументами.
Це, здається, зовсім не свідчить про різну поведінку. Я не бачу жодних інших відповідних посилань на " -x" в посібнику. Він не описує відмінності в послідовності запуску.
Пояснення : У таких системах, як типовий Linux-скриньку, де ' /bin/sh' є символьним посиланням на ' /bin/bash' (або де б не було знайдено виконуваний файл Bash), два командні рядки досягають еквівалентного ефекту від запуску скрипта із слідом виконання. В інших системах (наприклад, Solaris і деяких більш сучасних варіантах Linux) /bin/shне є Bash, і два командні рядки дали б (трохи) різні результати. Найголовніше, що ' /bin/sh' плутатимуть конструкції в Баші, які він зовсім не визнає. (На Solaris /bin/sh- оболонка Bourne; в сучасному Linux це іноді Dash - менша, більш строга оболонка, призначена лише для POSIX.) Коли викликається така назва, рядок 'shebang' (' #!/bin/bash' vs '#!/bin/sh'
У посібнику Bash є розділ про режим Bash POSIX, який, всупереч давній, але помилковій версії цієї відповіді (див. Також коментарі нижче), докладно описує різницю між "Bash посилається як sh" і "Bash викликається як bash'.
Під час налагодження сценарію оболонки (Bash) обов`язково і розумно - навіть необхідно - використовувати оболонку, названу в рядку shebang, за допомогою -xпараметра. В іншому випадку ви можете (будете?) Отримувати іншу поведінку під час налагодження від виконання сценарію.
bashсценарій. І запуск bash-скрипту з ним sh -xпризведе до того, що він поводиться зовсім інакше! Будь ласка, оновіть свою відповідь.
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
Я використовував наступні методи для налагодження мого сценарію.
set -eзмушує сценарій негайно зупинятися, якщо будь-яка зовнішня програма повертає ненульовий статус виходу. Це корисно, якщо ваш скрипт намагається обробити всі випадки помилок, і якщо невдача цього повинна бути захоплена.
set -x Згадано вище і, безумовно, є найбільш корисним з усіх методів налагодження.
set -n може бути корисним, якщо ви хочете перевірити свій скрипт на наявність синтаксичних помилок.
straceтакож корисно подивитися, що відбувається. Особливо корисно, якщо ви самі не написали сценарій.
strace -fце потрібно, якщо ви також хочете знайти помилки в процесах, запущених сценарієм. (що робить його в багато разів більш багатослівним, але все ж корисним, якщо ви обмежите його на системні дзвінки, які вас цікавлять).
set -eє ... суперечливим .
Ця відповідь є дійсною та корисною: https://stackoverflow.com/a/951352
Але я вважаю, що "стандартні" методи налагодження сценарію неефективні, неінтуїтивні та важкі у використанні. Для тих, хто звик до складних налагоджувачів графічного інтерфейсу, які ставлять усе під рукою і роблять роботу легким для легких проблем (і можливих для важких проблем), ці рішення не дуже задовільні.
Що я роблю, це використовувати комбінацію DDD та bashdb. Перший виконує останній, а останній виконує ваш сценарій. Це забезпечує багатовіконний інтерфейс з можливістю переходити до коду в контексті та переглядати змінні, стеки тощо, без постійних розумових зусиль, щоб підтримувати контекст у вашій голові або продовжувати повторне перерахування джерела.
Тут є вказівки щодо налаштування цього веб-сайту: http://ubuntuforums.org/showthread.php?t=660223
Ви також можете написати "set -x" в сценарії.
Я знайшов утиліту shellcheck і, можливо, хтось вважає це цікавим https://github.com/koalaman/shellcheck
Маленький приклад:
$ cat test.sh
ARRAY=("hello there" world)
for x in $ARRAY; do
echo $x
done
$ shellcheck test.sh
In test.sh line 3:
for x in $ARRAY; do
^-- SC2128: Expanding an array without an index only gives the first element.
виправте помилку, спершу спробуйте ...
$ cat test.sh
ARRAY=("hello there" world)
for x in ${ARRAY[@]}; do
echo $x
done
$ shellcheck test.sh
In test.sh line 3:
for x in ${ARRAY[@]}; do
^-- SC2068: Double quote array expansions, otherwise they're like $* and break on spaces.
Спробуємо ще раз ...
$ cat test.sh
ARRAY=("hello there" world)
for x in "${ARRAY[@]}"; do
echo $x
done
$ shellcheck test.sh
знайдіть зараз!
Це лише невеликий приклад.
Скористайтеся затемненням із вбудованими плагінами та вбраннями.
https://sourceforge.net/projects/shelled/?source=directory https://sourceforge.net/projects/basheclipse/?source=directory
Для обстрілу: завантажте zip та імпортуйте його у затемнення за допомогою довідки -> встановіть нове програмне забезпечення: локальний архів Для basheclipse: Скопіюйте банки в каталог крапель затемнення
Виконайте вказівки https://sourceforge.net/projects/basheclipse/files/?source=navbar
Я написав підручник з багатьма скріншотами на http://dietrichschroff.blogspot.de/2017/07/bash-enabling-eclipse-for-bash.html
Я побудував налагоджувач Bash. Просто спробуйте. Сподіваюся, це допоможе https://sourceforge.net/projects/bashdebugingbash
встановити + x = @ECHO OFF, встановити -x = @ECHO ON.
Ви можете додати -xvваріант до стандартного Shebang наступним чином:
#!/bin/bash -xv
-x: Відображення команд та їх аргументів під час їх виконання.
-v: Відображення ліній введення оболонки під час їх зчитування.
ltrace- це ще одна утиліта Linux, схожа на strace. Однак ltraceперелічені всі дзвінки бібліотеки, що викликаються у виконаному або запущеному процесі. Сама назва походить від трасування викликів бібліотеки. Наприклад:
ltrace ./executable <parameters>
ltrace -p <PID>
Я думаю, ви можете спробувати цей відладчик Bash: http://bashdb.sourceforge.net/ .
set -[nvx]Окрім
set -x
і
set +x
для зупинки звалища.
Я хотів би поговорити про те, set -vщо звалище має менший розмір та менш розвинену продукцію.
bash <<<$'set -x\nfor i in {0..9};do\n\techo $i\n\tdone\nset +x' 2>&1 >/dev/null|wc -l
21
for arg in x v n nx nv nvx;do echo "- opts: $arg"
bash 2> >(wc -l|sed s/^/stderr:/) > >(wc -l|sed s/^/stdout:/) <<eof
set -$arg
for i in {0..9};do
echo $i
done
set +$arg
echo Done.
eof
sleep .02
done
- opts: x
stdout:11
stderr:21
- opts: v
stdout:11
stderr:4
- opts: n
stdout:0
stderr:0
- opts: nx
stdout:0
stderr:0
- opts: nv
stdout:0
stderr:5
- opts: nvx
stdout:0
stderr:5
Для тестування деяких змінних я використовую колись це:
bash <(sed '18ideclare >&2 -p var1 var2' myscript.sh) args
для додавання:
declare >&2 -p var1 var2
у рядку 18 та запущений результуючий скрипт (з аргументами ), не потребуючи їх редагування.
Звичайно, це можна використати для додавання set [+-][nvx]:
bash <(sed '18s/$/\ndeclare -p v1 v2 >\&2/;22s/^/set -x\n/;26s/^/set +x\n/' myscript) args
буде додано declare -p v1 v2 >&2після рядка 18, set -xперед рядком 22 та set +xперед рядком 26.
bash <(sed '2,3s/$/\ndeclare -p LINENO i v2 >\&2/;5s/^/set -x\n/;7s/^/set +x\n/' <(
seq -f 'echo $@, $((i=%g))' 1 8)) arg1 arg2
arg1 arg2, 1
arg1 arg2, 2
declare -i LINENO="3"
declare -- i="2"
/dev/fd/63: line 3: declare: v2: not found
arg1 arg2, 3
declare -i LINENO="5"
declare -- i="3"
/dev/fd/63: line 5: declare: v2: not found
arg1 arg2, 4
+ echo arg1 arg2, 5
arg1 arg2, 5
+ echo arg1 arg2, 6
arg1 arg2, 6
+ set +x
arg1 arg2, 7
arg1 arg2, 8
Примітка: на піклування про $LINENOце впливатимуть модифікації, які будуть на ходу !
(Щоб побачити отриманий скрипт без виконання, просто опустіть bash <(і ) arg1 arg2)
Погляньте на мою відповідь про те, як профілювати bash-скрипти
Існує велика кількість деталей щодо реєстрації скриптів оболонки за допомогою глобальних змінних оболонок. Ми можемо наслідувати подібний тип входу в сценарій оболонки: http://www.cubicrace.com/2016/03/log-tracing-mechnism-for-shell-scripts.html
У публікації є детальна інформація про вхідні рівні журналів, такі як INFO, DEBUG, ERROR. Деталі відстеження, такі як запис сценарію, вихід сценарію, введення функції, вихід функції.
Приклад журналу: