How can I write a heredoc to a file in Bash script? How can I write a heredoc to a file in Bash script? bash bash

How can I write a heredoc to a file in Bash script?


Read the Advanced Bash-Scripting Guide Chapter 19. Here Documents.

Here's an example which will write the contents to a file at /tmp/yourfilehere

cat << EOF > /tmp/yourfilehereThese contents will be written to the file.        This line is indented.EOF

Note that the final 'EOF' (The LimitString) should not have any whitespace in front of the word, because it means that the LimitString will not be recognized.

In a shell script, you may want to use indentation to make the code readable, however this can have the undesirable effect of indenting the text within your here document. In this case, use <<- (followed by a dash) to disable leading tabs (Note that to test this you will need to replace the leading whitespace with a tab character, since I cannot print actual tab characters here.)

#!/usr/bin/env bashif true ; then    cat <<- EOF > /tmp/yourfilehere    The leading tab is ignored.    EOFfi

If you don't want to interpret variables in the text, then use single quotes:

cat << 'EOF' > /tmp/yourfilehereThe variable $FOO will not be interpreted.EOF

To pipe the heredoc through a command pipeline:

cat <<'EOF' |  sed 's/a/b/'foobarbazEOF

Output:

foobbrbbz

... or to write the the heredoc to a file using sudo:

cat <<'EOF' |  sed 's/a/b/' | sudo tee /etc/config_file.conffoobarbazEOF


Instead of using cat and I/O redirection it might be useful to use tee instead:

tee newfile <<EOFline 1line 2line 3EOF

It's more concise, plus unlike the redirect operator it can be combined with sudo if you need to write to files with root permissions.


Note:

The question (how to write a here document (aka heredoc) to a file in a bash script?) has (at least) 3 main independent dimensions or subquestions:

  1. Do you want to overwrite an existing file, append to an existing file, or write to a new file?
  2. Does your user or another user (e.g., root) own the file?
  3. Do you want to write the contents of your heredoc literally, or to have bash interpret variable references inside your heredoc?

(There are other dimensions/subquestions which I don't consider important. Consider editing this answer to add them!) Here are some of the more important combinations of the dimensions of the question listed above, with various different delimiting identifiers--there's nothing sacred about EOF, just make sure that the string you use as your delimiting identifier does not occur inside your heredoc:

  1. To overwrite an existing file (or write to a new file) that you own, substituting variable references inside the heredoc:

    cat << EOF > /path/to/your/fileThis line will write to the file.${THIS} will also write to the file, with the variable contents substituted.EOF
  2. To append an existing file (or write to a new file) that you own, substituting variable references inside the heredoc:

    cat << FOE >> /path/to/your/fileThis line will write to the file.${THIS} will also write to the file, with the variable contents substituted.FOE
  3. To overwrite an existing file (or write to a new file) that you own, with the literal contents of the heredoc:

    cat << 'END_OF_FILE' > /path/to/your/fileThis line will write to the file.${THIS} will also write to the file, without the variable contents substituted.END_OF_FILE
  4. To append an existing file (or write to a new file) that you own, with the literal contents of the heredoc:

    cat << 'eof' >> /path/to/your/fileThis line will write to the file.${THIS} will also write to the file, without the variable contents substituted.eof
  5. To overwrite an existing file (or write to a new file) owned by root, substituting variable references inside the heredoc:

    cat << until_it_ends | sudo tee /path/to/your/fileThis line will write to the file.${THIS} will also write to the file, with the variable contents substituted.until_it_ends
  6. To append an existing file (or write to a new file) owned by user=foo, with the literal contents of the heredoc:

    cat << 'Screw_you_Foo' | sudo -u foo tee -a /path/to/your/fileThis line will write to the file.${THIS} will also write to the file, without the variable contents substituted.Screw_you_Foo