Как отладить скрипт bash? [закрытый]



есть ли способ отладить сценарий bash? Например, то, что печатает своего рода журнал выполнения как "линия 1", "Линия 2" и т. д.

651   13  

13 ответов:

sh -x script [arg1 ...]
bash -x script [arg1 ...]

они дают вам след того, что выполняется. (См. также "разъяснение" в нижней части ответа.)

иногда вам нужно контролировать отладку в скрипте. В таком случае, как Читоснапоминает меня, вы можете использовать:

set -x

это включает отладку. Затем вы можете снова отключить его:

set +x

(вы можете узнать текущее состояние трассировки путем анализа $-, в текущие флаги, для x.)

кроме того, оболочки обычно предоставляют опции'-n ' за 'без казни 'и'-v 'для режима 'verbose'; вы можете использовать их в сочетании, чтобы увидеть, считает ли оболочка, что она может выполнить ваш скрипт - иногда полезно, если у вас есть несбалансированная цитата где-то.


есть утверждение, что '-x' опция в Bash отличается от других оболочек (см. комментарии). Элемент Bash Manual говорит:

  • - x

    печать трассировки простых команд, for команды case команды select команды и арифметика for команды и их аргументы или связанные списки слов после их расширения и до их выполнения. Значение PS4 переменная расширяется и результирующее значение выводится перед командой и ее расширенными аргументами.

это, похоже, не указывает совсем другое поведение. Я не вижу никаких других соответствующих ссылок на '-x в руководстве. Он не описывает различия в последовательности запуска.

уточнение: в системах, таких как типичный Linux box, где '/bin/sh 'является символической ссылкой на'/bin/bash' (или везде, где находится исполняемый файл Bash), две командные строки достигают эквивалентного эффекта запуска сценария с трассировкой выполнения. На других системах (например, Solaris и некоторые другие современные варианты Linux),/bin/sh это не Bash, и две командные строки дадут (немного) разные результаты. В частности, '/bin/sh ' были бы смущены конструкциями в Bash, которые он вообще не признает. (На Солярисе,/bin/sh является оболочкой Bourne; на современном Linux это иногда тире - меньшая, более строго POSIX-только оболочка.) При вызове по имени, как это, строку 'притон' ('#!/bin/bash ' vs '#!/bin/sh') в начале файла не влияет на содержание интерпретированный.

в руководстве Bash есть раздел режим bash POSIX который, в отличие от давней, но ошибочной версии этого ответа (см. также комментарии ниже), подробно описывает разницу между " Bash вызывается как sh ' и ' Bash вызывается как bash'.

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

я использовал следующие методы для отладки мой сценарий.

set -e немедленно останавливает скрипт, если какая-либо внешняя программа возвращает ненулевое состояние выхода. Это полезно, если ваш скрипт пытается обработать все случаи ошибок и где сбой должен быть заблокирован.

set -x было упомянуто выше и, безусловно, является наиболее полезным из всех методов отладки.

set -n также может быть полезно, если вы хотите проверить свой скрипт на синтаксис ошибки.

strace также полезно посмотреть, что происходит. Особенно полезно, если вы не написали сценарий.

этот ответ действителен и полезен:https://stackoverflow.com/a/951352

но я считаю, что" стандартные " методы отладки скриптов неэффективны, неинтуитивны и трудны в использовании. Для тех, кто привык к сложным ОТЛАДЧИКАМ GUI, которые ставят все под рукой и делают работу легкой для легких проблем (и возможной для сложных проблем), эти решения не очень удовлетворительны.

то, что я делаю, это использовать комбинацию 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

сейчас найти!

это просто небольшой пример.

Я построил отладчик Bash. Просто дайте ему попробовать. Я надеюсь, что это поможет https://sourceforge.net/projects/bashdebugingbash

установить VSCode, затем добавьте расширение отладки bash, и вы готовы к отладке в визуальном режиме. смотрите здесь в действии.

enter image description here

Я думаю, вы можете попробовать этот отладчик Bash:http://bashdb.sourceforge.net/.

набор +х = @Эхо выключено, комплект-х = @Echo на.


вы можете добавить в стандартный набор выглядит следующим образом:

#!/bin/bash -xv  

-x: отображение команд и их аргументов по мере их выполнения.
-v: отображение входных строк оболочки по мере их чтения.


ltrace это еще одна утилита Linux, похожая на strace. Однако,ltrace список всех вызовов библиотеки, вызываемых в исполняемом или запущенном файле процесс. Само его название происходит от трассировки библиотечных вызовов. Например:

ltrace ./executable <parameters>  
ltrace -p <PID>  

источник

какой-то трюк для отладки Баш скрипт:

используя 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 и запуск результирующего скрипта (с args), без необходимости их редактирования.

конечно, это может быть использовано для добавления 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

используйте eclipse с плагинами shelled & basheclipse.

https://sourceforge.net/projects/shelled/?source=directory https://sourceforge.net/projects/basheclipse/?source=directory

для shelled: загрузите zip и импортируйте его в eclipse через help - > установите новое программное обеспечение : локальный архив для basheclipse: скопируйте банки в каталог dropins eclipse

выполните следующие действия обеспечивает https://sourceforge.net/projects/basheclipse/files/?source=navbar

enter image description here

Я написал учебник со многими скриншотами на http://dietrichschroff.blogspot.de/2017/07/bash-enabling-eclipse-for-bash.html

есть достаточное количество деталей на входе для shell-скриптов через мировой varaibles оболочки. Мы можем эмулировать подобный вид входа в сценарий оболочки:http://www.cubicrace.com/2016/03/log-tracing-mechnism-for-shell-scripts.html

в сообщении есть сведения об уровнях журнала introducing , таких как информация, отладка, ошибка. Подробности трассировки как запись сценария, выйти из сценария, запись, функция выхода.

образец журнал:

enter image description here

писать сообщения об ошибках Bash

shell-скрипт-это текстовый файл, содержащий команды оболочки. По умолчанию интерпретатор команд и утилиты оболочки отображают сообщения об ошибке и диагностические сообщения о стандартной ошибке. Bash может печатать трассировку запущенного скрипта, если xtrace опция включена.

пример кода печатает след в файле xtrace.log. Функция err позволяет быстро идентифицировать сообщения об ошибках. След функции err отменен, потому что его текущая среда выполнения скрывает информацию, которая формирует трассировку.

пример кода

#!/bin/bash
set -o errexit

exec 4>xtrace.log
BASH_XTRACEFD=4
PS4='+ : line ${LINENO}: ${FUNCNAME[0]}: '
set -x

echo 'Welcome!'

err()
{
   printf "%s\n" "${BASH_SOURCE[0]}: line ${BASH_LINENO[0]}: ${FUNCNAME[0]}: "
} >&2 4>/dev/null

err 'oops, something went wrong!'

этот пример выводит код:

prompt% my_script
Welcome
./my_script: line 16: err: oops, something went wrong!

сообщения об ошибках могут быть перенаправлены, чтобы скрыть диагностические сообщения:

prompt% my_script 2>err.log
Welcome!

посмотрите на трассировку и посмотрите ошибки и диагностические сообщения:

prompt% cat xtrace.log
+ ./my_script: line 9: main: echo Welcome
+ ./my_script: line 16: main: err 'oops, something went wrong!'
prompt% cat err.log
./my_script: line 16: err: oops, something went wrong!

Comments

    Ничего не найдено.