[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: substitution "read all from fd" silently fails: $(<&0)

From: Stephane Chazelas
Subject: Re: substitution "read all from fd" silently fails: $(<&0)
Date: Wed, 1 Jul 2015 22:48:02 +0100
User-agent: Mutt/1.5.21 (2010-09-15)

2015-07-01 22:19:10 +0300, Ilya Basin:
> Hi list.
> Want to read whole stdin into variable.
> Don't want to spawn new processes (cat).

Note that

$(<file) does spawn a new process, it's just that bash doesn't
execute /bin/cat in that process, it does the reading (from
file) and writing (to the pipe) by itself (and the parent reads
from the other end of the pipe to make-up the substitution).

ksh (ksh93 and mksh) and zsh do not spawn a process in the
$(<file) case.

For any other type of redirection (like $(<&0) or even $(<file
2>&3), it doesn't work in ksh either, (in ksh, like in bash,
$(<file) really is an operator of its own), while in zsh, we're
in the non-optimised case, it's just a command with only
redirections (which happens to be in a command substitution), so
the the $NULLCMD (cat by default) command is run.

I'd use $(cat) in bash. After all a shell is the command to run
other commands. The costly part in there is the forking and
shoving the data through a pipe (which is done any way on
$(<file), not so much the executing of cat.

If you want to avoid the fork, as others have said, you can use
IFS= read -rd '' var < file

That will also have the advantage of not removing the trailing
characters from file. Yes, it stops at the first NUL byte in
file, but bash variables (contrary to zsh's) can't hold NUL
bytes anyway.

Another alternative is to use readarray:

readarray var

which stores each line of stdin (including the trailing newline
unless you use -t) into each element of the $var array.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]