There are many ways to save a multi line string in bash.
This is post just shows how to output a multiline string.
The Basics – Quoting Variables
From the bash(1) man page:
1 2 3 |
If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. |
Also single quotes(e.g. ‘EOF’) or double quotes(e.g. “EOF”) can be used as stop tokens
The minus trims leading spaces or blanks. The quotes around the token prevent variable expansion inside document.
Examples
i. heredoc with variable expansion
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
cat > myfile.txt <<EOF this file has $variable $names $inside EOF #print out the content of myfile.txt cat myfile.txt #this file has variable="ONE" names="TWO" inside="expanded variables" cat > myfile.txt <<EOF this file has $variable $names $inside EOF #print out the content of myfile.txt cat myfile.txt #this file has ONE TWO expanded variables |
ii. heredoc without variable expansion
1 2 3 4 5 6 7 |
cat > myfile.txt <<"EOF" this file has $variable $dollar $name $inside EOF #print out the content of myfile.txt cat myfile.txt #this file has $variable $dollar $name $inside |
The quoted “EOF” directive is determines whether or not variable name inside the multi line string will be expanded.
iii. heredoc without variable expansion – example 2
1 2 3 4 5 6 7 8 |
cat > myfile.txt <<EOF this file has $variable \$dollar \$name \$inside EOF #print out the content of myfile.txt cat myfile.txt #this file has $variable $dollar $name $inside |
Escaping dollar inside a heredoc string is error prone and should be avoided!
So option ii. is the best
1. Set Multi Line Text to a String Variable
1 2 3 4 5 6 7 8 |
read -d '' stringvar <<-"_EOF_" all the leading dollars in the $variable $name are $retained _EOF_ echo $stringvar; # all the leading dollars in the $variable $name are $retained |
2. Set Multi Line Text to a String Variable
1 2 3 4 5 6 |
read -d '' help <<- "_EOF_" usage: up [--level <n>| -n <levels>][--help][--version] Report bugs to: up home page: _EOF_ |
3. Set Multi Line Text to a String Variable
1 2 3 4 5 6 |
VARIABLE1="<?xml version=\"1.0\" encoding='UTF-8'?> <report> <img src="a-vs-b.jpg"/> <caption>Thus is a future post on Multi Line Strings in bash <date>1511</date>-<date>1512</date>.</caption> </report>" |
4. Set Multi Line Text to a String Variable
1 2 3 4 5 6 7 8 9 |
VARIABLE2=$(cat <<EOF <?xml version="1.0" encoding='UTF-8'?> <report> <img src="a-vs-b.jpg"/> <caption>Thus is a future post on Multi Line Strings in bash <date>1511</date>-<date>1512</date>.</caption> </report> EOF ) |
5. Set Multi Line Text to a String Variable
1 2 3 4 5 6 7 8 |
VARABLE3=`cat <<EOF <?xml version="1.0" encoding='UTF-8'?> <report> <img src="a-vs-b.jpg"/> <caption>Thus is a future post on Multi Line Strings in bash <date>1511</date>-<date>1512</date>.</caption> </report> EOF` |
6. Save A Multi Line String to a Text File
1 2 3 4 5 |
cat > heredocfile.txt <<_EOF_ I am line 1 I am line 2 I'm the last line _EOF_ |
Test File Contents
1 |
cat heredocfile.txt |
1 2 3 |
# and then, change your echo statement to include the '-e' option # which will turn on escape sequence processing: echo -e $USAGE >&2 |
7. Save A Multi Line String to a Text File
this redirect does not work …
1 2 3 4 5 6 7 8 |
sudo cat > /aaaa.txt <<_EOF_ I am line 1 I am line 2 I'm the last line _EOF_ # sudo and >>: permission denied # Fix below |
8. Save A Multi Line String to a Text File
1 2 3 4 |
# create sudo tee /aaa.txt << EOF echo "Hello World 20314" EOF |
9. Append a Multi Line String to a Text File
1 2 3 4 |
# Append to Sudo sudo tee -a /aaa.txt << EOF echo "This Line is appended" EOF |
10. Save Multi Line String to a Text File
1 2 3 4 5 6 |
sudo sh -c "cat > /aaa.txt" <<"EOT" this text gets saved as sudo - $10 - ten dollars ... EOT cat /aaa.txt #this text gets saved as sudo - $10 - ten dollars ... |
11. Save Multi Line String to a Text File
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
cat << "EOF" | sudo tee /aaa.txt let's count $one two $three four EOF cat /aaa.txt #let's count #$one #two #$three #four |
tee –help
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
> tee --help Usage: tee [OPTION]... [FILE]... Copy standard input to each FILE, and also to standard output. -a, --append append to the given FILEs, do not overwrite -i, --ignore-interrupts ignore interrupt signals --help display this help and exit --version output version information and exit If a FILE is -, copy again to standard output. Report tee bugs to bug-coreutils@gnu.org GNU coreutils home page: <http://www.gnu.org/software/coreutils/> General help using GNU software: <http://www.gnu.org/gethelp/> For complete documentation, run: info coreutils 'tee invocation' |
References
1. Heredoc Quoting – Credit to Ignacio Vazquez-Abrams: http://serverfault.com/questions/399428/how-do-you-escape-characters-in-heredoc
2. eredoc Quoting – Credit to Dennis Williamson: http://stackoverflow.com/questions/3731513/how-do-you-type-a-tab-in-a-bash-here-document
3. http://serverfault.com/questions/72476/clean-way-to-write-complex-multi-line-string-to-a-variable
4. http://arstechnica.com/civis/viewtopic.php?p=21091503
5. http://superuser.com/questions/201829/sudo-permission-denied
6. http://stackoverflow.com/questions/4937792/using-variables-inside-a-bash-heredoc
7. http://stackoverflow.com/questions/2600783/how-does-the-vim-write-with-sudo-trick-work
8. http://www.unix.com/shell-programming-scripting/187477-variables-heredoc.html