20

I would like to output this on completion of my bash script.

 /\_/\
( o.o )
 > ^ <

I have tried the following but all return errors.

echo /\\_/\\\n\( o.o \)\n > ^ <
echo  \/\\_\/\\\r\n( o.o )\r\n > ^ <
echo /\\_/\\\n\( o.o \)\n \> ^ <

How do I escape these characters so that bash renders them as a string?

8
  • 2
    I can't help wondering whether there is a meaning to the output, or whether it's a useless use of cat 😜
    – IMSoP
    Nov 26, 2021 at 18:21
  • It's probably a UUoC but as long as you aren't relying on ASCII art elsewhere in your program then it should be OK :D For me, there is no meaning to the output on this occasion, I just wanted to echo a cat on termination. Nov 26, 2021 at 19:30
  • 1
    @IMSoP This is a very useful use of a cat! Nov 27, 2021 at 12:59
  • 1
    @IsmaelMiguel agreed - if you can think of a better one feel free to change it Nov 28, 2021 at 11:31
  • 1
    @JamesGeddes I'm bad at titles... What you wrote is way better than anything I can come up with. Nov 30, 2021 at 7:30

2 Answers 2

38

In this case, I'd use cat with a (quoted) here-document:

cat <<'END_CAT'
 /\_/\
( o.o )
 > ^ <
END_CAT

This is the best way of ensuring the ASCII art is outputted the way it is intended without the shell "getting in the way" (expanding variables etc., interpreting backslash escape sequences, or doing redirections, piping etc.)

You could also use a multi-line string with printf:

printf '%s\n' ' /\_/\
( o.o )
 > ^ <'

Note the use of single quotes around the static string that we want to output. We use single quotes to ensure that the ASCII art is not interpreted in any way by the shell. Also note that the string that we output is the second argument to printf. The first argument to printf is always a single quoted formatting string, where backslashes are far from inactive.

Or multiple strings with printf (one per line):

printf '%s\n' ' /\_/\' '( o.o )' ' > ^ <'
printf '%s\n' \
' /\_/\' \
'( o.o )' \
' > ^ <'

Or, with echo (but see Why is printf better than echo? ; basically, depending on the shell and its current settings, there are possible issues with certain escape sequences that may not play nice with ASCII drawings),

echo ' /\_/\
( o.o )
 > ^ <'

But again, just outputting it from a here-document with cat would be most convenient and straight-forward I think.

7
  • 12
    Love the suggestion to cat a cat :D Nov 24, 2021 at 18:41
  • 6
    Or cat << '🐈' or cat << '😼' :-) Nov 24, 2021 at 18:55
  • 2
    @they This answer is purrrfect, so gets teh cheezburger. Thanks! Thanks too to everyone else for contributing! Nov 25, 2021 at 10:15
  • Note there are several kinds of here-documents depending on what level of processing you need. Nov 27, 2021 at 13:00
  • @ThorbjørnRavnAndersen As far as I understand, there is only on type of here-document. They may be quoted or un-quoted though. Is that what you mean?
    – they
    Nov 27, 2021 at 16:39
15

Quote it with single '' or double quotes "" to prevent the <>() from being taken as operators. Then if you want it on one line, use echo -e or $' ' in Bash, mark the newlines as \n and escape the backslashes with another backslash. Or rather use printf to avoid issues with the differences between echo in various environments.

So:

$ printf ' /\\_/\\\n( o.o )\n > ^ <\n'
 /\_/\
( o.o )
 > ^ <
$ printf "%s\n" $' /\\_/\\\n( o.o )\n > ^ <'
 /\_/\
( o.o )
 > ^ <  

See also:

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.