Jordi Nebot
Jordi Nebot

Reputation: 3401

How to output error in custom color in Vagrant provision script?

I want my Vagrant provision script to run some checks that will require user action if they're not satisfied. As easy as:

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

But, as long as this is not a real error, I got the echo printed in green. I'd like my output to be red (or, a different color at least) to alert the user.

I tried:

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

that works locally, but on Vagrant output the color code gets escaped and I got it echoed in green instead.

Is that possible?

Upvotes: 2

Views: 1635

Answers (4)

Utkonos
Utkonos

Reputation: 795

Here is a bash script test.sh which should demonstrate how to output to stderr or stdout conditionally. This form is good for a command like [ / test or touch that does not return any stdout or stderr normally. This form is checking the exit status code of the command which is stored in $?.

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

You can alternatively hard code your file path like your question shows:

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

If you have output of the command, but its being sent to stderr rather than stdout and ending up in red in the Vagrant output, you can use the following forms to redirect the output to where you would expect it to be. This is good for commands like update-grub or wget.

wget

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

update-grub

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

One Liners

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

Upvotes: 0

manofthepeace
manofthepeace

Reputation: 11

You need to use keep_color true then it works as intended;

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

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

keep_color (boolean) - Vagrant automatically colors output in green and red depending on whether the output is from stdout or stderr. If this is true, Vagrant will not do this, allowing the native colors from the script to be outputted.

Upvotes: 1

maxrodrigo
maxrodrigo

Reputation: 1850

This is happening because some tools write some of their messages to stderr, which Vagrant then interprets as an error and prints in red.

Not all terminals support ANSI colour codes and Vagrant don't take care of that. Said that, I won't suggest colorizing a word by sending it to stderr unless it is an error.

To achieve that you can simply:

echo "Your error message" > /dev/stderr

Upvotes: 3

alessandrocb
alessandrocb

Reputation: 698

Vagrant commands runs by default with --no-color option. You could try to set color on with --color. The environmental variables for Vagrant are documented here.

Upvotes: 0

Related Questions