Как выполнить скрипт bash построчно?

96

Если я введу параметр bash -x , он покажет всю строку. Но сценарий будет нормально выполняться.

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

Родриго
источник
1
Возможно, в более широком смысле см. Также stackoverflow.com/questions/951336/how-to-debug-a-bash-script/…
Tripleee

Ответы:

130

Вам не нужно помещать чтение в каждую строку, просто добавьте ловушку, подобную приведенной ниже, в свой сценарий bash, она даст желаемый эффект, например.

#!/usr/bin/env bash
set -x
trap read debug

< YOUR CODE HERE >

Работает, только что протестировал с bash v4.2.8 и v3.2.25.


УЛУЧШЕННАЯ ВЕРСИЯ

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

#!/usr/bin/env bash
echo "Press CTRL+C to proceed."
trap "pkill -f 'sleep 1h'" INT
trap "set +x ; sleep 1h ; set -x" DEBUG

< YOUR CODE HERE >

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


АЛЬТЕРНАТИВА1

Если вы просто хотите подождать несколько секунд, прежде чем переходить к следующей команде в сценарии, следующий пример может сработать для вас.

#!/usr/bin/env bash
trap "set +x; sleep 5; set -x" DEBUG

< YOUR CODE HERE >

Я добавляю set + x и set -x в команду trap, чтобы сделать вывод более читаемым.

органическое мэшап
источник
1
Тогда как перейти к следующей строке (выполнить следующую команду)?
Дэвид Дориа,
2
Он улавливает чтение каждой команды. Единственное, что вам нужно сделать, это нажать клавишу возврата, чтобы перейти к следующей команде
organic-mashup
1
если у вас есть такие командные строки, как "while read line; do echo $ line; done <somefile" этот метод не работает, потому что "trap read DEBUG" считывает строку из somefile
mug896
3
Как это остановить? После того как я прохожу сценарий до конца, оболочка ведет себя так, как будто сценарий все еще запущен.
slashdottir
1
Измените на, trap 'read -u1' debugчтобы переопределить проблему перенаправления чтения файла.
user3132194
23

Может быть, отладчик BASH для вас.


источник
3
Это действительно лучшее решение. Это позволяет просматривать строку до ее запуска (и многое другое). В большинстве систем его можно установить с помощью apt-get install bashdb. Затем вам просто нужно запустить bashdb your_command.sh, ввести stepи после этого нажать возврат каретки.
Studgeek
1
@studgeek недоступен в Redhat / CentOS и т.д., поэтому я бы не назвал это «большинством систем».
Sajuuk
@Sajuuk, может, не упакован , но абсолютно доступен .
Чарльз Даффи,
macOS:brew install bashdb
boweeb
@CharlesDuffy: его тоже нет в репозиториях Ubuntu по умолчанию.
Дэн Даскалеску,
2

Если ваш сценарий bash на самом деле представляет собой набор разовых команд, которые вы хотите запускать одну за другой, вы можете сделать что-то вроде этого, который запускает каждую команду одну за другой, когда вы увеличиваете переменную LN, соответствующую номеру строки, которую вы хотите запустить . Это позволяет вам просто очень легко запустить последнюю команду снова, а затем вы просто увеличиваете переменную, чтобы перейти к следующей команде.

Предполагая, что ваши команды находятся в файле "it.sh", выполните следующие, одну за другой.

$ cat it.sh
echo "hi there"
date
ls -la /etc/passwd

$ $(LN=1 && cat it.sh | head -n$LN | tail -n1)
"hi there"

$ $(LN=2 && cat it.sh | head -n$LN | tail -n1)
Wed Feb 28 10:58:52 AST 2018

$ $(LN=3 && cat it.sh | head -n$LN | tail -n1)
-rw-r--r-- 1 root wheel 6774 Oct 2 21:29 /etc/passwd
Брэд Паркс
источник
1

xargs: может фильтровать строки

cat .bashrc | xargs -0 -l -d \\n bash
  • -0 Считать необработанным вводом (без экранирования)
  • -l Отделять каждую строку (Не по умолчанию для выступлений)
  • -d \\ n Разделитель строк
Тинмарино
источник