Как вывести ошибку в пользовательском цвете в сценарии предоставления Vagrant?

Я хочу, чтобы мой сценарий обеспечения Vagrant выполнял некоторые проверки, которые потребуют действий пользователя, если они не удовлетворены. Так же легко, как:

if [ ! -f /some/required/file ]; then
    echo "[Error] Please do required stuff before provisioning"
    exit
fi

Но, пока это не настоящая ошибка, я получил echo напечатано зеленым. Мне бы хотелось, чтобы мой вывод был красным (или, по крайней мере, другого цвета), чтобы предупредить пользователя.

Я старался:

echo "\033[31m[Error] Blah blah blah"

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

Это возможно?

4 ответа

Решение

Это происходит потому, что некоторые инструменты пишут свои сообщения stderr, который Vagrant затем интерпретирует как ошибку и печатает красным.

Не все терминалы поддерживают цветовые коды ANSI, а Vagrant об этом не заботится. Сказал, что я не буду предлагать раскрасить слово, отправив его stderr если это не ошибка.

Для этого вы можете просто:

echo "Your error message" > /dev/stderr

Вам нужно использовать keep_color true, тогда он работает как задумано;

config.vm.provision "shell", keep_color: true, inline: $echoes
$echoes = <<-ECHOES
echo "\e[32mPROVISIONING DONE\e[0m"
ECHOES

С https://www.vagrantup.com/docs/provisioning/shell.html

keep_color (boolean) - Vagrant автоматически раскрашивает вывод в зеленый и красный цвета в зависимости от того, идет ли вывод из stdout или stderr. Если это правда, Vagrant не будет этого делать, позволяя выводить собственные цвета из скрипта.

Вот баш-скриптtest.shкоторый должен продемонстрировать, как условно выводить на stderr или stdout. Эта форма хороша для такой команды, как[/testилиtouchкоторый обычно не возвращает stdout или stderr. Эта форма проверяет код состояния выхода команды, который хранится в$?.

      test -f $1
if [ $? -eq 0 ]; then
    echo "File exists: $1"
else
    echo "File not found: $1"
fi

В качестве альтернативы вы можете жестко указать путь к файлу, как показывает ваш вопрос:

      file="/some/required/file"
test -f $file
if [ $? -eq 0 ]; then
    echo "File exists: $file"
else
    echo "File not found: $file"
fi

Если у вас есть вывод команды, но он отправляется на stderr, а не на stdout и заканчивается красным цветом в выводе Vagrant, вы можете использовать следующие формы для перенаправления вывода туда, где вы ожидаете. Это хорошо для таких команд, как или .

      url='https://example.com/file'
out=$(wget --no-verbose $url 2>&1)
if [ $? -ne 0 ]; then
    echo "$out" > /dev/stderr
else
    echo "$out"
fi

      out=$(update-grub 2>&1)
if [ $? -ne 0 ]; then
    echo "$out" > /dev/stderr
else
    echo "$out"
fi

Один лайнер

wget

      url='https://example.com/file'
out=$(wget --no-verbose $url 2>&1) && echo "$out" || echo "$out" > /dev/stderr

update-grub

      out=$(update-grub 2>&1) && echo "$out" || echo "$out" > /dev/stderr

Команды Vagrant запускаются по умолчанию с --no-color вариант. Вы можете попытаться установить цвет с помощью --color, Переменные среды для Vagrant описаны здесь.

Другие вопросы по тегам