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. -- Stephane