4

In this question and in this question this kind of BASH script syntax is used:

#!/bin/bash
sql << EOF

**some SQL commands**

EOF

Where EOF can in fact be anything. It works for me, but I am curious why it works and how. What is the right way to call this pattern. And can you find the Bash documentation corresponding to this feature?

Community
  • 1
  • 1
exebook
  • 32,014
  • 33
  • 141
  • 226

2 Answers2

6
% man bash | grep --max-count=1 '<<' -C 7

Here Documents
   This type of redirection instructs the shell to read input from the current source until a line containing only delimiter (with no trailing  blanks)
   is seen.  All of the lines read up to that point are then used as the standard input for a command.

   The format of here-documents is:

          <<[-]word
                  here-document
          delimiter

   No  parameter  and variable expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word.  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.  If  word  is  unquoted,
   all  lines  of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion, the character sequence \<new‐
   line> is ignored, and \ must be used to quote the characters \, $, and `.
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
4

The construct you've found is called a "here document" and is described in the Bash manual under the heading "Here Documents" (followed by "Here Strings" that are related). It is a standard feature of any shell implementing the POSIX standard for shells. I believe that "here strings" is a Bash extension though.

It is good practice to do as in your example and use an upper-case string to mark the ending of the here document. Another good suggestions is to use XXX_END (with XXX being, e.g., XML, DOC, DATA, SQL or whatever it is you're feeding into the command) as the delimiter to further document the here document.

If the word used as a delimiter is quoted, the shell will not do parameter expansion (etc.) on the contents of the here document:

$ cat <<'TEST_END'
my $HOME is where I hang my hat
TEST_END

results in:

my $HOME is where I hang my hat

while

$ cat <<TEST_END
my $HOME is where I hang my hat
TEST_END

(on my laptop) results in

my /Users/kk is where I hang my hat
Kusalananda
  • 14,885
  • 3
  • 41
  • 52