Привет. Я часто использую 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): foo=10

echo ${bar}

+(./script.sh:7): echo 10

10

echo $((6 + 6))

+(./script.sh:8): echo 12

4



Теперь если скрипт где-то вылетает с плохим статусом (либо происходит что-то другое), всегда можно узнать в какой строке это приключилось, не бегая по огромному куску кода.



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



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



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



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



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



tags: #linux #bash #debug



💩 @bashdays