I'm wondering when using cat <<
is preferable over simply using <<
. I'm testing in a ZSH shell and
cat <<EOF
Hello world!
EOF
outputs the same of
<<EOF
Hello world!
EOF
.
var=$(cat <<EOF
Hello world!
EOF
)
has the same variable value of
var=$(<<EOF
Hello world!
EOF
)
What are the practical differences between the two forms of here-doc?
cat is a bash command used to read, display, or concatenate the contents of a file, while EOF stands for End Of File. The EOF is an indication to the shell that the file that was being read has ended. cat << eof uses here-document.
I'm referring mainly to cat << EOF, I know > outputs to a file, >> appends to a file, < reads input from file. What does << exactly do? And is there a man page for it? Show activity on this post. The cat <<EOF syntax is very useful when working with multi-line text in Bash, eg. when assigning multi-line string to a shell variable, file or a pipe.
Let’s get back to the point that EOF is not a character. What is a character anyway? A character is the smallest component of a text. ‘A’, ‘a’, ‘B’, ‘b’ are all different characters. A character has a numeric value that is called a code point in the Unicode standard.
Let’s see how we can detect the EOF condition in various programming languages when reading a text file using high-level I/O routines provided by the languages. For this purpose, we’ll write a very simple cat version called mcat that reads an ASCII -encoded text file byte by byte (character by character) and explicitly checks for EOF.
As long as zsh default behavior (for example invoking zsh -f
), there is no defference between the two examples. We could check the trace output with invoking the two examples with zsh -x -f
, cat
will be called actually even in the latter case.
Although these differences are described in Redirections with no command, zshmisc(1)
. zsh will behave in several ways for redirections with no command, so we can do about it to not break anything:
cat
explicitly.Redirections with no command
When a simple command consists of one or more redirection operators and zero or more parameter assignments, but no command name, zsh can behave in several ways.
If the parameter NULLCMD is not set or the option CSH_NULLCMD is set, an error is caused. This is the csh behavior and CSH_NULLCMD is set by default when emulating csh.
If the option SH_NULLCMD is set, the builtin ‘:’ is inserted as a command with the given redirections. This is the default when emulating sh or ksh.
Otherwise, if the parameter NULLCMD is set, its value will be used as a command with the given redirections. If both NULLCMD and READNULLCMD are set, then the value of the latter will be used instead of that of the former when the redirection is an input. The default for NULLCMD is ‘cat’ and for READNULLCMD is ‘more’.Thus
< file
shows the contents of file on standard output, with paging if that is a terminal. NULLCMD and READNULLCMD may refer to shell functions.
-- Redirections with no command,
zshmisc(1)
So, in the latter case, $var
will not be set if the zsh shell option SH_NULLCMD
is set, etc.
# I've tested with running `zsh -f` to check the various behaviors.
test-nullcmd () {
local var=$(<<EOF
Hello world!
EOF
)
echo "$var"
}
test-nullcmd
#> Hello world!
() {
setopt localoptions shnullcmd
test-nullcmd
}
# nothing will be printed
() {
setopt localoptions cshnullcmd
test-nullcmd
}
# test-nullcmd:1: redirection with no command (error)
() {
local NULLCMD=
test-nullcmd
}
# test-nullcmd:1: redirection with no command (error)
BTW, we could use command cat
rather than cat
solely to prevent alias expansions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With