6

I'm used to use cat > /path/to/file << EOF when I, in a bash script, printed more than one line into a file... I was checking old code of my company and I found the cat EOT instruction instead of the cat EOF I'm used to (please notice the T instead of the F at the end of it) and curiosity bit me.

I did a quick research and I only found this other question, but I think it was not related to what I wanted to know.

I did some tests with the following code:

password=hello
cat > ./hello.txt << EOT
authentication {
    auth_type PASS
    auth_pass $password
  }
EOT

And I get the exact same output as when I use EOF instead of EOT. The output is, as expected:

root@test_VM:~# bash test.sh && cat hello.txt

authentication { auth_type PASS auth_pass hello }

So the questions are:

  1. What are the differences between the use of EOT and EOF?
  2. When should I use one over the other?
k.Cyborg
  • 487

2 Answers2

25

There is no difference, and no particular meaning to those two strings, or any others. It's just an arbitrary terminator and you can use almost any string you like.

Of course, the data itself can't contain that particular line, so if your data contains e.g. a shell script that has another here-doc, you'll need to use different terminators in both. Using somewhat descriptive strings may be useful for any future readers of the script.

E.g.

cat > test.sh <<END_OF_SCRIPT
cat <<EOF
hello
EOF
END_OF_SCRIPT

produces test.sh which, when executed through the shell prints hello.

There is a difference if you quote the terminator in the line that starts the here-doc, though, it'll prevent expansions in the here-doc data. This prints $i, not whatever the value of the variable is:

cat << 'EOF'
$i
EOF

See also:

ilkkachu
  • 138,973
  • Thanks you very much sir! I didn't knew and I was stucked with the classic EOF – k.Cyborg Jun 08 '22 at 19:22
  • 3
    @k.Cyborg The label could be used for documentation, to a degree. For example, your code in the question could use AUTH_CONF_END or a similar label. – Kusalananda Jun 08 '22 at 19:24
  • 1
    Beware there are some limitations as to what characters can be used as the delimiter. If it's otherwise a character special to the shell such as ;, (, ', #, then it has to be quoted, and then than means expansions are no longer performed inside. Even when quoted, using newline in the delimiter works in few shells (only dash and ksh93 in the few shells I tried). – Stéphane Chazelas Jun 08 '22 at 20:08
  • 5
    I've used things like :||:<<'# some comment' for instance to comment out some code up to # some comment for instance. – Stéphane Chazelas Jun 08 '22 at 20:08
  • 1
    @StéphaneChazelas, why the :|| ? – ilkkachu Jun 08 '22 at 20:28
  • 6
    @ilkkachu to avoid the heredoc being created at all (at least in modern shells, IIRC in earlier versions of the Bourne shell, the here doc would still be created) – Stéphane Chazelas Jun 08 '22 at 20:31
  • @StéphaneChazelas, right, right, the shell doesn't have to create the temp file for it. Makes it look rather arcane, too ;) – ilkkachu Jun 08 '22 at 20:34
  • "…no particular meaning to those two strings…" depends on how you define 'meaning'. EOF is generally used to indicate End Of File (https://en.wikipedia.org/wiki/End-of-file) and in this context the heredoc content is the "file". EOT is likely a reference to End Of Transmission (https://en.wikipedia.org/wiki/End-of-Transmission_character). Neither do anything special in this context compare to FOO or AUTH_CONF_END or even an intentionally confusing KEEP_GOING_DO_NOT_STOP_HERE, but there is a meaning or convention for the person reading/writing the code. – IBBoard Jun 09 '22 at 19:32
  • Might be worth linking to the relevant manual page for GNU Bash: https://www.gnu.org/software/bash/manual/bash.html#Here-Documents – shadowtalker Jun 09 '22 at 20:50
  • 1
    @IBBoard, no particular meaning for the shell that interprets the text, I mean. – ilkkachu Jun 09 '22 at 21:01
  • I thought so, but worth clarifying the origins for people wondering what "EOF" means and why some strings use "EOT" instead. – IBBoard Jun 11 '22 at 08:38
  • EOF...EOT...in a word (or two), "mnemonic device". I'm so old, I saw EOT as "end of tape". – gbarry Jun 11 '22 at 18:18
2

Let me answer your second question first.

That is, you should use whatever your project coding style guideline requires - or if there isn't one, your own consistent preference.

The code editor I use generates "EOF" whenever I type the here-doc operators eventhough I personally prefer "!" which is actually not a special character to the shell. (It's a reserved word that happen to be usable as a here-doc delimiter)

Back to the first question. EOT is actually an ASCII control character that, by convention on Unix systems, generates the End-Of-File indication to the program reading terminal input, when the terminal settings had not been otherwise altered.

So distinguishing EOF and EOT can in a way signify the purpose of the here-doc content, in addition to delimiting overlapping portions of different here-doc.

Finally. That other question you linked asked for explanation why EOF has a different value than EOT. And as explained, EOF is a condition, whereas EOT is a valid byte value and character, and EOF is generated by a EOT character under default terminal settings.

DannyNiu
  • 620
  • 5
  • 19