У меня есть скрипт bash с различными операторами if, основанными на аргументах командной строки, которые я передаю при его вызове. Наличие некоторого вывода о том, какие команды выполняются, полезно для подтверждения прохождения всех этих операторов if, но мое текущее решение дает мне слишком много информации.
Использование set -v
в сценарии было несколько полезно, чтобы увидеть команды, выводимые на экран, так как они выполнялись в сценарии, однако я получаю слишком много команд. Это почти как полная копия сценария.
Я хочу вывод, который показывает, какие команды выполняются, но я не хочу видеть комментарии, новые строки, выражения в операторах if и т. Д.
Есть ли способ, которым я могу передать все возможные выходные данные, генерируемые параметром -v, через регулярное выражение перед печатью? Или какое-то другое решение, позволяющее bash выводить только команды определенного «типа» (например, использующие исполняемые файлы, а не только определенные операторы bash, комментарии и т. Д.?)
[1] /programming/257616/sudo-changes-path-why был весьма полезен в этом вопросе и именно здесь я получил предложение об set -v
использовании.
Редактировать :
Сценарий, похожий (но не идентичный) на тот, который я запускаю:
#!/bin/bash
#get verbose command output
set -v
env=$1
if [ "$env" == "dev" ]; then
python ascript.py
fi
if [ "$env" == "prod" ]; then
#launching in prod will most likely fail if not run as root. Warn user if not running as root.
if [ $EUID -ne 0 ]; then
echo "It doesn't look like you're running me as root. This probably won't work. Press any key to continue." > /dev/stderr
read input
fi
#"stop" any existing nginx processes
pkill -f nginx
nginx -c `pwd`/conf/artfndr_nginx.conf
fi
Я хочу только 2 возможных набора выходных строк из этого скрипта. Первый:
python ascript.py
Секунда:
pkill -f nginx
nginx -c /some/current/directory/conf/artfndr_nginx.conf
источник
set -v
вывода вам нужны, а какие нет.Ответы:
Когда я пишу более сложные сценарии bash, я использую небольшую функцию для запуска команд, которая также выводит команды, запущенные в лог-файл:
Затем в моем скрипте я запускаю команды, подобные этой:
Если вы не хотите печатать команду, просто запустите ее как обычно.
Вы можете установить
$LOG
имя файла или просто удалить его и распечатать в stdout или stderr.источник
v python ascript.py
без необходимости заключать в кавычки и терять подсветку кода vimeval ..... || ok=1
: установит нормально "1", только когда произойдет сбой "eval ..." ?? Может быть, вы имели в виду "&&"? И если вы это имели в виду, добавьте «ok = 0» перед строкой eval, чтобы она «сбрасывалась» каждый раз. Или просто переименовать «ок» в «ошибка»? кажется, это то, что здесь подразумевалось. Итак, в итоге:eval "$@" 2>> "$LOG" && error=0 || error=1
ok
переменная, которая остановит скрипт, если какая-либо команда завершится неудачно. Так как это не имеет значения здесь, я удалил его, но забыл удалить|| ok=1
. Спасибо, исправлено."
окружающий оператор eval, потому что команда уже окружена"
sИспользуйте вложенную оболочку, то есть:
Например:
печать
источник
set -x; cmd; set +x
по нескольким причинам. Во-первых, он не сбрасывается,set -x
если он был включен ранее. Во-вторых, завершение скрипта внутри не приводит к выполнению ловушек с подробными настройками.Я видел методы, похожие на @ terdon's. Это начало того, что языки программирования более высокого уровня называют регистраторами и предлагают как полноценные библиотеки, такие как log4J (Java), log4Perl (Perl) и т. Д.
Вы можете получить что-то похожее, используя
set -x
Bash, как вы уже упоминали, но вы можете использовать это, чтобы включить отладку только для подмножества команд, обернув блоки кода с ними примерно так.Примеры
Вот один шаблон лайнера, который вы можете использовать.
Вы можете обернуть их так для нескольких команд в скрипте.
Log4Bash
Большинство людей не замечают, но у Bash также есть log4 *, Log4Bash . Если у вас более скромные потребности, возможно, стоит потратить время на его настройку.
Примеры
Вот несколько примеров использования log4bash.
Log4sh
Если вы хотите то, что я бы классифицировал как большую часть всей инфраструктуры log4 *, я бы попробовал Log4sh .
выдержка
Log4sh поддерживает несколько оболочек, а не только Bash.
Он также был протестирован на нескольких ОС, а не только на Linux.
Использование каркаса log4 * потребует некоторого времени для изучения, но оно того стоит, если у вас есть более требовательные потребности в вашей регистрации. Log4sh использует файл конфигурации, в котором вы можете определить приложения и управлять форматированием для вывода, который будет отображаться.
пример
Теперь, когда я запускаю это:
ПРИМЕЧАНИЕ. Приведенное выше конфигурирует appender как часть кода. При желании это можно извлечь в собственный файл и
log4sh.properties
т. Д.Обратитесь к отличной документации для Log4sh, если вам нужна дополнительная информация.
источник
set
команды, которые мне нужно ввести, чередование комментариев и т. Д., Поэтому просто наличие функции в верхней части моего скрипта с односимвольным вызовом функции, предшествующим все "важные" строки в сценарии мне пока казались более аккуратными. (один символ, потому что функция имеет одно имя символа)echo
свою собственную функциюmecho
, а затем передать переключатель в программу, вызываемую-v
для многословия, когда я хочу выключить вещи. Я также могу управлять им с помощью переключателя 2-го аргумента, который задает имя функции, поэтому у меня есть 2 оси для управления журналированием. Это часто - ворота к желанию log4bash все же.set -x
печатает команды по мере их выполнения. Он не печатает комментарии.set -x
практично для отладки (в отличие отset -v
чего не очень полезно). Zsh имеет лучший результат,set -x
чем bash, например, он показывает, какая функция выполняется в данный момент, и номер строки источника.Вы могли бы ,
trap
DEBUG
а затем проверить наBASH_COMMAND
переменную . Добавьте это в начало скрипта:Код читабелен; он просто проверяет, начинается ли первый аргумент с
python
илиpkill
, и печатает его, если это так. И ловушка используетBASH_COMMAND
(которая содержит команду, которая будет выполнена) в качестве первого аргумента.Обратите внимание, что хотя
case
используются глобусы, вы можете сделать это так же легко:И используйте регулярные выражения.
источник
Это пересмотренная версия аккуратной функции Стивена Пенни. Он печатает свои аргументы в цвете и цитирует их по мере необходимости. Используйте его для выборочного отображения команд, которые вы хотите отследить. Поскольку кавычки выводятся, вы можете скопировать напечатанные строки и вставить их в терминал для немедленного повторного выполнения во время отладки скрипта. Прочтите первый комментарий, чтобы узнать, что я изменил и почему.
Пример использования с выводом:
# xc echo "a b" "c'd" "'" '"' "fg" '' " " "" \# this line prints in green
echo 'a b' c\'d \' '"' fg '' ' ' '' '#' this line prints in green
a b c'd ' " fg # this line prints in green
Вторая строка выше печатается зеленым цветом и может быть скопирована для воспроизведения третьей строки.
Дальнейшие замечания
Оригинальный xc @ Steven-Penny умный, и он заслуживает всех кредитов за это. Однако я заметил некоторые проблемы, но я не мог прокомментировать его пост напрямую, потому что у меня недостаточно репутации. Поэтому я предложил изменить его пост, но рецензенты отклонили его. Поэтому я решил опубликовать свои комментарии в качестве этого ответа, хотя я бы предпочел иметь возможность редактировать собственный ответ Стива Пенни.
Что я изменил в ответе Стивена-Пенни
Исправлено: печать пустых строк - они не печатались. Исправлено: печать строк, которые включают
%
- они вызывали ошибки синтаксиса awk. Замененоfor (j in ...)
на,for (j = 0, ...)
потому что первое не гарантирует порядок обхода массива (это зависит от реализации awk). Добавлены 0 к восьмеричным числам для переносимости.Обновить
Стивен Пенни с тех пор исправил эти проблемы в своем ответе, поэтому эти замечания остаются только для исторической записи моего ответа. Смотрите раздел Комментарии для получения более подробной информации.
источник
Вы можете использовать функцию оболочки "sh_trace" из библиотеки POSIX stdlib, чтобы напечатать команду в цвете перед ее запуском. Пример:
Основная функция Awk:
источник