É $ () um subshell?

45

Eu entendo que a sintaxe subshell seja (<commands...>) , é $() apenas um subshell que você pode recuperar valores de variáveis de?

Nota: Isso se aplica ao bash 4.4 com base em diferentes palavras em sua documentação.

    
por leeand00 09.05.2018 / 08:31

3 respostas

66

$(…) é um subshell por definição: é uma cópia do estado de tempo de execução do shell¹, e alterações no estado feito no subshell não causam impacto no pai. Um subshell é tipicamente implementado por forking um novo processo (mas alguns shells podem otimizar isso em alguns casos). / p>

Não é um subshell que você pode recuperar valores de variáveis. Se as alterações nas variáveis tivessem um impacto no pai, não seria uma sub-novidade. É um subshell cujo output o pai pode recuperar. O subshell criado por $(…) tem sua saída padrão definida como um pipe, e o pai lê desse pipe e coleta a saída.

Existem várias outras construções que criam um subshell. Eu acho que esta é a lista completa de bash:

  • Subshell para o agrupamento : ( … ) não faz nada mas crie uma subshell e espere que ela termine). Contraste com { … } , que agrupa comandos puramente para propósitos sintáticos e não cria um subnível.
  • Background : … & cria uma subshell e não espera que ela termine.
  • Pipeline : … | … cria duas subpavinas, uma para o lado esquerdo e um para o lado direito, e aguarda que ambos terminem. O shell cria um pipe e conecta a saída padrão do lado esquerdo à extremidade de gravação do pipe e a entrada padrão do lado direito ao terminal de leitura. Em alguns shells (ksh88, ksh93, zsh, bash com o lastpipe option definido e efetivo), o lado direito é executado no shell original, portanto, a construção do pipeline cria apenas um subshell.
  • Substituição de comandos : $(…) (também escrito '…' ) cria uma subshell com sua saída padrão definida para um pipe, coleta a saída no pai e se expande para essa saída, menos suas novas linhas finais. (E a saída pode estar sujeita a divisão e globbing, mas isso é outra história.)
  • Processo de substituição : <(…) cria um subshell com seu padrão saída definida para um pipe e se 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 pipe na entrada padrão.
  • Coprocess : coproc … cria uma subshell e não espera que ela termine . A entrada e a saída padrão do subshell são definidas para um pipe com o pai sendo conectado à outra extremidade de cada pipe.

¹ Como oposta à execução de um shell separado .

    
por 09.05.2018 / 10:30
20

Na página man do bash (1) na versão 4.4 do bash, na seção "EXPANSION", na subseção "Substituição de Comando":

Bash performs the expansion by executing command in a subshell environment [...]

    
por 09.05.2018 / 08:33
5

Sim, ( commands... ) é um subgrupo bash que executará commands... em outro processo.

A única diferença quando você tem $( commands... ) é que esta parte do código irá após a execução de commands... ser substituída por tudo o que commands... escreveu para stdout .

    
por 09.05.2018 / 10:39