How to output a multiline string in Bash?

How can I output a multipline string in Bash without using multiple echo calls like so:

echo "usage: up [--level <n>| -n <levels>][--help][--version]"
echo 
echo "Report bugs to: "
echo "up home page: "

I'm looking for a portable way to do this, using only Bash builtins.


Solution 1:

Here documents are often used for this purpose.

cat << EOF
usage: up [--level <n>| -n <levels>][--help][--version]

Report bugs to: 
up home page:
EOF

They are supported in all Bourne-derived shells including all versions of Bash.

Solution 2:

or you can do this:

echo "usage: up [--level <n>| -n <levels>][--help][--version]

Report bugs to: 
up home page: "

Solution 3:

Inspired by the insightful answers on this page, I created a mixed approach, which I consider the simplest and more flexible one. What do you think?

First, I define the usage in a variable, which allows me to reuse it in different contexts. The format is very simple, almost WYSIWYG, without the need to add any control characters. This seems reasonably portable to me (I ran it on MacOS and Ubuntu)

__usage="
Usage: $(basename $0) [OPTIONS]

Options:
  -l, --level <n>              Something something something level
  -n, --nnnnn <levels>         Something something something n
  -h, --help                   Something something something help
  -v, --version                Something something something version
"

Then I can simply use it as

echo "$__usage"

or even better, when parsing parameters, I can just echo it there in a one-liner:

levelN=${2:?"--level: n is required!""${__usage}"}

Solution 4:

Use -e option, then you can print new line character with \n in the string.

Sample (but not sure whether a good one or not)

The fun thing is that -e option is not documented in MacOS's man page while still usable. It is documented in the man page of Linux.