$(…)é um subshell por definição: é uma cópia do estado de tempo de execução do shell¹, e as alterações no estado feitas no subshell não têm impacto no pai. Um subshell é normalmente implementado bifurcando um novo processo (mas alguns shells podem otimizar isso em alguns casos).
Não é um subshell do qual você pode recuperar valores de variáveis. Se as alterações nas variáveis tivessem um impacto no pai, não seria um subshell. É um subshell cuja saída o pai pode recuperar. O subshell criado por $(…)tem sua saída padrão definida como um pipe, e o pai lê esse pipe e coleta a saída.
Existem várias outras construções que criam um subshell. Acho que esta é a lista completa do bash:
Subshell para agrupamento : ( … )não faz nada além de criar um subshell e esperar que ele termine). Compare com { … }o qual agrupa comandos puramente para propósitos sintáticos e não cria um subshell.
Background : … &cria um subshell e não espera que ele termine.
Pipeline : … | …cria dois subshells, um para o lado esquerdo e outro para o lado direito, e espera que ambos terminem. O shell cria um pipe e conecta a saída padrão do lado esquerdo ao final de gravação do pipe e a entrada padrão do lado direito ao final de leitura. Em alguns shells (ksh88, ksh93, zsh, bash com a lastpipeopção definida e efetiva), o lado direito é executado no shell original, portanto, a construção do pipeline cria apenas um subshell.
Substituição de comando : $(…)(também escrito `…`) cria um subshell com sua saída padrão definida como um canal, coleta a saída no pai e expande para essa saída, menos suas novas linhas à direita. (E a saída pode estar ainda mais sujeita a divisão e globbing, mas isso é outra história.)
Substituição de processo : <(…)cria um subshell com sua saída padrão definida como um pipe e expande para o nome do pipe. O pai (ou algum outro processo) pode abrir o pipe para se comunicar com o subshell. >(…)faz o mesmo, mas com o tubo na entrada padrão.
Coprocess : coproc …cria um subshell e não espera que ele termine. A entrada e a saída padrão do subshell são definidas para um tubo com o pai sendo conectado à outra extremidade de cada tubo.
Sim, ( commands... )é um bashsubshell que irá executar commands...em outro processo.
A única diferença quando você tem $( commands... )é que esta parte do código após a execução commands...será substituída por tudo o que foi commands...gravado em stdout.
$(…)
é um subshell por definição: é uma cópia do estado de tempo de execução do shell¹, e as alterações no estado feitas no subshell não têm impacto no pai. Um subshell é normalmente implementado bifurcando um novo processo (mas alguns shells podem otimizar isso em alguns casos).Não é um subshell do qual você pode recuperar valores de variáveis. Se as alterações nas variáveis tivessem um impacto no pai, não seria um subshell. É um subshell cuja saída o pai pode recuperar. O subshell criado por
$(…)
tem sua saída padrão definida como um pipe, e o pai lê esse pipe e coleta a saída.Existem várias outras construções que criam um subshell. Acho que esta é a lista completa do bash:
( … )
não faz nada além de criar um subshell e esperar que ele termine). Compare com{ … }
o qual agrupa comandos puramente para propósitos sintáticos e não cria um subshell.… &
cria um subshell e não espera que ele termine.… | …
cria dois subshells, um para o lado esquerdo e outro para o lado direito, e espera que ambos terminem. O shell cria um pipe e conecta a saída padrão do lado esquerdo ao final de gravação do pipe e a entrada padrão do lado direito ao final de leitura. Em alguns shells (ksh88, ksh93, zsh, bash com alastpipe
opção definida e efetiva), o lado direito é executado no shell original, portanto, a construção do pipeline cria apenas um subshell.$(…)
(também escrito`…`
) cria um subshell com sua saída padrão definida como um canal, coleta a saída no pai e expande para essa saída, menos suas novas linhas à direita. (E a saída pode estar ainda mais sujeita a divisão e globbing, mas isso é outra história.)<(…)
cria um subshell com sua saída padrão definida como um pipe e expande para o nome do pipe. O pai (ou algum outro processo) pode abrir o pipe para se comunicar com o subshell.>(…)
faz o mesmo, mas com o tubo na entrada padrão.coproc …
cria um subshell e não espera que ele termine. A entrada e a saída padrão do subshell são definidas para um tubo com o pai sendo conectado à outra extremidade de cada tubo.¹ Ao contrário de executar um shell separado .
Na página do manual bash(1) na versão 4.4 do bash, seção "EXPANSION", subseção "Substituição de comandos":
Sim,
( commands... )
é umbash
subshell que irá executarcommands...
em outro processo.A única diferença quando você tem
$( commands... )
é que esta parte do código após a execuçãocommands...
será substituída por tudo o que foicommands...
gravado emstdout
.