I'm asking only about the usage which would have the similar effect as traditional input redirection from a file.
<<<"$(<file)"
as far as I can tell is equivalent to
<file
It appears to me that these are functionally equivalent. At the low level it appears that the <<< here document might actually cause more copies of the data to be in memory at once.
I know this type of redirection exists in both bash and zsh but I'm not familiar with how it's implemented, though I see the zsh manpages contain some implementation details.
Best Answer
In
<<<"$(<file)"
(supported byzsh
(where<<<
was first introduced, inspired by the same operator in the Unix port ofrc
),ksh93
(the$(<file)
operator was introduced byksh
),mksh
andbash
),For
$(<file)
, the shell reads the content of thefile
(chokes on NUL bytes except forzsh
), removes all the trailing newline characters and that makes the expansion of$(<file)
(so the content of the file is stored as a whole in memory).For
<<< some-text
, the shell storessome-text
followed by one newline character into a temporary file, and opens that temporary file on the file descriptor 0.So basically
<<<"$(<file)"
opens stdin for reading on a temporary copy offile
where trailing newline characters have been replaced by just one (and with various misbehaviours if the file contains NUL bytes, except inzsh
).While in
< file
, it'sfile
that is directly opened for reading on stdin.Of course
< file
is much more efficient (doesn't involve a copy on disk and in memory), but one might want to use the<<<"$(<file)"
to make sure the file open on stdin is a regular file, or to make sure the file has been fully read by the time the command is started (in case that command writes to it for instance) or another redirection is processed (like one that would truncatefile
as intr 1 2 <<< "$(<file)" > file
).Note that
yash
supports the<<<
operator (though implements it with a pipe (so not a regular file) instead of a temporary file). but not the$(<file)
one. You can use<<<"$(cat < file)"
instead there.yash
strings are characters only, so the"$(cat < file)"
will choke on sequences of bytes that don't form valid characters, while other shells can usually cope OK with them.