Você quis dizer apenas no contexto do agrupamento de comandos?
heemayl
Respostas:
87
Se você deseja que os efeitos colaterais da lista de comandos afetem seu shell atual , use {...}
Se você deseja descartar quaisquer efeitos colaterais, use(...)
Por exemplo, eu poderia usar um subshell se eu:
quero alterar $IFSpara alguns comandos, mas não quero alterar $IFSglobalmente para o shell atual
cdem algum lugar, mas não quero alterar o $PWDshell atual
Vale a pena notar que os parênteses podem ser usados em uma definição de função:
uso normal: chaves: corpo da função é executado no shell atual; efeitos colaterais permanecem após a função ser concluída
Após muitos anos de desenvolvimento de shell, eu não sabia que você poderia usar parênteses para executar funções em subshells. Que ótima idéia para evitar poluir o espaço para nome global!
L0b0:
7
O uso da localpalavra - chave ajuda bastante na limpeza dessa poluição.
glenn jackman
2
Sim, mas você deve se lembrar de declarar todas as variáveis locais, e isso atrapalha o código.
L0b0
4
Dica: Se você deseja funções sem efeito colateral, mas evita a sintaxe incomum de declaração de função (da qual os editores de código podem não estar cientes), basta usar parênteses na chamada de função em vez da declaração:pwd; (count_tmp); pwd;
Juve
2
para o shell ... foo () (:;) é equivalente a foo () {(:;); } É assim que ele relata, se você perguntar!
Colocar uma lista de comandos entre parênteses causa a criação de um ambiente de subshell, e cada um dos comandos na lista é executado nesse subshell. Como a lista é executada em um subshell, as atribuições de variáveis não permanecem em vigor após a conclusão do subshell.
{}
{ list;}
Colocar uma lista de comandos entre chaves faz com que a lista seja executada no contexto atual do shell. Nenhum subshell é criado. É necessário o ponto e vírgula (ou nova linha) a seguir.
O código em '{}' é executado no thread / processo / ambiente atual e as alterações são preservadas, para ser mais sucinto, o código é executado no escopo atual.
O código em '()' é executado dentro de um processo filho separado do bash que é descartado após a execução. Esse processo filho geralmente é chamado de subcasca e pode ser considerado como um novo escopo infantil.
Observe no primeiro exemplo com '{}' a variável ainda está definida mesmo após o fechamento '}', enquanto no exemplo com '()' a variável não está definida fora do escopo de '()'.
Respostas:
Se você deseja que os efeitos colaterais da lista de comandos afetem seu shell atual , use
{...}
Se você deseja descartar quaisquer efeitos colaterais, use
(...)
Por exemplo, eu poderia usar um subshell se eu:
$IFS
para alguns comandos, mas não quero alterar$IFS
globalmente para o shell atualcd
em algum lugar, mas não quero alterar o$PWD
shell atualVale a pena notar que os parênteses podem ser usados em uma definição de função:
uso normal: chaves: corpo da função é executado no shell atual; efeitos colaterais permanecem após a função ser concluída
uso incomum: parênteses: o corpo da função é executado em um subshell; efeitos colaterais desaparecem quando o subshell sai
Documentação
fonte
local
palavra - chave ajuda bastante na limpeza dessa poluição.pwd; (count_tmp); pwd;
A partir da documentação oficial do bash :
fonte
O código em '{}' é executado no thread / processo / ambiente atual e as alterações são preservadas, para ser mais sucinto, o código é executado no escopo atual.
O código em '()' é executado dentro de um processo filho separado do bash que é descartado após a execução. Esse processo filho geralmente é chamado de subcasca e pode ser considerado como um novo escopo infantil.
Como exemplo, considere o seguinte ...
Observe no primeiro exemplo com '{}' a variável ainda está definida mesmo após o fechamento '}', enquanto no exemplo com '()' a variável não está definida fora do escopo de '()'.
fonte
(...)
são usados para executar código em um sub-shell. O código usado bewteen{...}
não será usado em um sub-shell.fonte