Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assign a heredoc value to a variable in Bash?

Tags:

bash

heredoc

I have this multi-line string (quotes included):

abc'asdf" $(dont-execute-this) foo"bar"'' 

How would I assign it to a variable using a heredoc in Bash?

I need to preserve newlines.

I don't want to escape the characters in the string, that would be annoying...

like image 745
Neil Avatar asked Jul 22 '09 19:07

Neil


People also ask

How do you set a variable value in bash?

To create a variable, you just provide a name and value for it. Your variable names should be descriptive and remind you of the value they hold. A variable name cannot start with a number, nor can it contain spaces. It can, however, start with an underscore.

How does bash implement heredoc?

To use here-document in any bash script, you have to use the symbol << followed by any delimiting identifier after any bash command and close the HereDoc by using the same delimiting identifier at the end of the text.

What is heredoc delimiter?

Heredoc uses 2 angle brackets (<<) followed by a delimiter token. The same delimiter token will be used to terminate the block of code. Whatever comes within the delimiter is considered to be a block of code.

What is heredoc syntax?

The heredoc syntax is a way to declare a string variable. The heredoc syntax takes at least three lines of your code and uses the special character <<< at the beginning.


2 Answers

You can avoid a useless use of cat and handle mismatched quotes better with this:

$ read -r -d '' VAR <<'EOF' abc'asdf" $(dont-execute-this) foo"bar"'' EOF 

If you don't quote the variable when you echo it, newlines are lost. Quoting it preserves them:

$ echo "$VAR" abc'asdf" $(dont-execute-this) foo"bar"'' 

If you want to use indentation for readability in the source code, use a dash after the less-thans. The indentation must be done using only tabs (no spaces).

$ read -r -d '' VAR <<-'EOF'     abc'asdf"     $(dont-execute-this)     foo"bar"''     EOF $ echo "$VAR" abc'asdf" $(dont-execute-this) foo"bar"'' 

If, instead, you want to preserve the tabs in the contents of the resulting variable, you need to remove tab from IFS. The terminal marker for the here doc (EOF) must not be indented.

$ IFS='' read -r -d '' VAR <<'EOF'     abc'asdf"     $(dont-execute-this)     foo"bar"'' EOF $ echo "$VAR"     abc'asdf"     $(dont-execute-this)     foo"bar"'' 

Tabs can be inserted at the command line by pressing Ctrl-V Tab. If you are using an editor, depending on which one, that may also work or you may have to turn off the feature that automatically converts tabs to spaces.

like image 107
Dennis Williamson Avatar answered Sep 22 '22 09:09

Dennis Williamson


Use $() to assign the output of cat to your variable like this:

VAR=$(cat <<'END_HEREDOC' abc'asdf" $(dont-execute-this) foo"bar"'' END_HEREDOC )  # this will echo variable with new lines intact echo "$VAR" # this will echo variable without new lines (changed to space character) echo $VAR 

Making sure to delimit starting END_HEREDOC with single-quotes.

Note that ending heredoc delimiter END_HEREDOC must be alone on the line (hence ending parenthesis is on the next line).

Thanks to @ephemient for the answer.

like image 24
Neil Avatar answered Sep 18 '22 09:09

Neil