O Que É um Subshell? Um Shell Filho para Isolamento
Um subshell é um processo de shell filho que roda um grupo de comandos em sua própria cópia do ambiente, então mudanças dentro dele não afetam o pai.
Às vezes o shell gera uma cópia filha de si mesmo, um subshell, para rodar um grupo de comandos em isolamento. Mudanças de variáveis e de diretório dentro de um subshell desaparecem quando ele termina. Isso é útil para escopo, mas também é uma fonte clássica de confusão quando uma variável misteriosamente não persiste.
O que é um subshell
Um subshell é um processo de shell separado, forkado do atual. Ele herda o ambiente do pai, mas quaisquer mudanças que faz, como definir uma variável ou mudar de diretório, ficam locais a ele.
Como subshells são criados
- Parênteses:
( cd build && make )roda em um subshell. - Um pipeline: cada lado de um
|pode rodar em seu próprio subshell. - Command substitution:
$(...)roda seu comando em um subshell.
O efeito de isolamento
Como um subshell tem sua própria cópia do ambiente, ( cd /tmp ) não muda o diretório do pai após retornar. Esse isolamento é o objetivo, mas surpreende pessoas que esperam que mudanças persistam.
Uma armadilha comum
Uma variável definida dentro de um loop com pipe pode não sobreviver, porque o loop rodou em um subshell. find . | while read f; do count=$((count+1)); done pode deixar count inalterado no pai.
Subshells no CI
Em scripts de CI, subshells ajudam a agrupar comandos sem poluir o shell externo, como rodar um build em um subdiretório. Mas se você depender de uma variável definida dentro de um subshell mais tarde, ela estará vazia, o que causa bugs difíceis de identificar.
Scripts previsíveis em runners gerenciados
Nos runners da Latchkey, usar um subshell para dar escopo a uma mudança de diretório mantém o resto do seu passo limpo. Apenas lembre-se de que valores que você precisa depois devem ser capturados no shell pai, não definidos dentro do subshell.
Principais conclusões
- Um subshell é um shell filho rodando comandos em uma cópia isolada do ambiente.
- Mudanças dentro de um subshell, como cd ou variáveis, não persistem para o pai.
- Parênteses, pipelines e
$(...)todos criam subshells em scripts.