I understand the subshell syntax to be (<commands...>), is $() just a subshell that you can retrieve variable values from?
Note: This applies to bash 4.4 based on different wording in their documentation.
I understand the subshell syntax to be (<commands...>), is $() just a subshell that you can retrieve variable values from?
Note: This applies to bash 4.4 based on different wording in their documentation.
$(…) is a subshell by definition: it's a copy of the shell runtime state¹, and changes to the state made in the subshell have no impact on the parent. A subshell is typically implemented by forking a new process (but some shells may optimize this in some cases).
It isn't a subshell that you can retrieve variable values from. If changes to variables had an impact on the parent, it wouldn't be a subshell. It's a subshell whose output the parent can retrieve. The subshell created by $(…) has its standard output set to a pipe, and the parent reads from that pipe and collects the output.
There are several other constructs that create a subshell. I think this is the full list for bash:
( … ) does nothing but create a subshell and wait for it to terminate). Contrast with { … } which groups commands purely for syntactic purposes and does not create a subshell.… & creates a subshell and does not wait for it to terminate.… | … creates two subshells, one for the left-hand side and one for the right-hand side, and waits for both to terminate. The shell creates a pipe and connects the left-hand side's standard output to the write end of the pipe and the right-hand side's standard input to the read end. In some shells (ksh88, ksh93, zsh, bash with the lastpipe option set and effective), the right-hand side runs in the original shell, so the pipeline construct only creates one subshell.$(…) (also spelled `…`) creates a subshell with its standard output set to a pipe, collects the output in the parent and expands to that output, minus its trailing newlines. (And the output may be further subject to splitting and globbing, but that's another story.)<(…) creates a subshell with its standard output set to a pipe and expands to the name of the pipe. The parent (or some other process) may open the pipe to communicate with the subshell. >(…) does the same but with the pipe on standard input.coproc … creates a subshell and does not wait for it to terminate. The subshell's standard input and output are each set to a pipe with the parent being connected to the other end of each pipe.From the bash(1) man page in bash version 4.4, "EXPANSION" section, "Command Substitution" subsection:
Bash performs the expansion by executing
commandin a subshell environment [...]
Yes, ( commands... ) is a bash subshell that will execute commands... in another process.
The only difference when you have $( commands... ) is that this part of code will after execution of commands... be replaced with everything that commands... wrote to stdout.