Привет. Я часто использую set -xve для отладки Bash-скриптов. Вообще это мастхэв-фича именно на момент, когда ты что-то создаёшь. Ведь не всегда логика может работать правильно (в моих случаях так и есть), а с set -xve ты вовремя можешь увидеть все значения переменных и т. п., не используя мусорные конструкции в своих поделках типа echo «Error in function xxx».

Конструкцию с set я обычно вставляю в shebang либо после, отдельным сетом:

#!/bin/bash -xve

set -xve

<script body>

Ключики команды set:

  • x — выводим команды и их аргументы по мере их выполнения.
  • v — выводим строки ввода командной строки по мере их считывания.
  • e — немедленный выход, если команда завершается с ненулевым статусом.

Окей. Как-то дебажил один большой и сложный скрипт на овердохуя строк. В какой-то момент скрипт завершался с ошибкой. В режиме отладки set -xve я видел, где он упал. Но мне хотелось знать — а на какой строке это произошло? Номера строк, увы, не выводятся, а по поиску и визуально искать — ну такое себе.

Эхх, одна задача превратилась в другую. В общем, решил разок упороться и проресерчить этот вопрос, на будущее, так сказать. По итогу получилось так.

Изменяем PS4 и добавляем вывод номера строки во включённый дебаг-режим:

#!/bin/bash -xve

PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

bar=10
echo ${bar}
echo $((6 + 6))

После выполнения скрипта получаем нумерацию строк:

bar=10
+(./script.sh:6): bar=10
echo ${bar}
+(./script.sh:7): echo 10
10
echo $((6 + 6))
+(./script.sh:8): echo 12
12
Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Теперь, если скрипт где-то вылетает с плохим статусом, всегда можно узнать, в какой строке это приключилось, не бегая по огромному куску кода.

Ну а чтобы добавить визуального оргазма, экспортируем PS4 так:

PS4='\033[0;33m+(${BASH_SOURCE}:${LINENO}):\033[0m ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

Происходит подкрашивание запускаемых строчек.

С помощью PS4 мы можем отладить shell-скрипт, задав при его выполнении set -x, что позволяет выводить каждую команду, а затем её результаты. Перед каждой командой ставится знак +, эту строку подсказки «+» можно изменить, определив переменную PS4.

Берите на вооружение. Хорошего дебага и с пятницей. Берегите себя!