One of the things I've noticed about BASH and other UNIX shells is that, by default and when used in typical ways, they spawn subshells for almost everything.
e.g.
foo=$(grep "someword" /path/to/somefile | awk '{print $3}')
would spawn two new sessions of bash just to load some text into a variable.
a) Why do shells do this? If a command line program operates on file descriptors, one shouldn't need to spawn a new non-interactive shell session just to feed it a descriptor, right?
b) How can I best work around this, when loading command output into variables? I know that in bash you can use:
read -r -d '' < <(...)
to set a variable from a command without using a subshell, but this rather cumbersome, and I'm looking for better (and more portable) methods. (Likewise it would be cool if anyone knew general alternatives to pipes and command substitution that did not involve subshells.)
NB: I know "user Perl/Python/Ruby" is probably the "correct" solution, but those all tend to need a lot of boilerplate code to do file manipulation, external command invocation, etc.
Edit: thanks for the answers below, however this still does not explain why process substitution must fork new shells even for builtin commands:
$ builtin echo $(builtin echo $(builtin echo $BASH_SUBSHELL))
2
exec
. – eyoung100 Sep 23 '14 at 16:10exec 2>/dev/null
– eyoung100 Sep 23 '14 at 16:32foo=$(grep ... | awk)
spawns one subshell, for the command substitution. – chepner Sep 26 '14 at 2:09foo=$(awk '/someword/ {print $3}' /path/to/somefile)
... – jasonwryan Oct 30 '14 at 0:10