Есть ли способ отладки скрипта 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
' будет смущен конструкциями в Bash, которые он вообще не распознает. (В 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
найди сейчас!
Это всего лишь маленький пример.
Используйте Eclipse с плагинами и панцирями.
https://sourceforge.net/projects/shelled/?source=directory https://sourceforge.net/projects/basheclipse/?source=directory
Для шелуша: загрузите zip и импортируйте его в eclipse с помощью справки -> установите новое программное обеспечение: локальный архив Для basheclipse: скопируйте jar-файлы в директорию dropins eclipse
Следуйте инструкциям на 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
опцию к стандартному Шебангу следующим образом:
#!/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. Отслеживание таких деталей, как запись скрипта, выход скрипта, запись функции, выход из функции.
Пример журнала: