Estou estudando scripts de shell com o bash e preciso saber a diferença entre (...)
e {...}
. Como alguém seleciona entre os dois ao escrever um script?
Estou estudando scripts de shell com o bash e preciso saber a diferença entre (...)
e {...}
. Como alguém seleciona entre os dois ao escrever um script?
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
$ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
$ pwd; count_tmp; pwd
/home/jackman
11
/tmp
$ echo "${#files[@]}"
11
uso incomum: parênteses: o corpo da função é executado em um subshell; efeitos colaterais desaparecem quando o subshell sai
$ cd ; unset files
$ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
$ pwd; count_tmp; pwd
/home/jackman
11
/home/jackman
$ echo "${#files[@]}"
0
local
palavra - chave ajuda bastante na limpeza dessa poluição.
pwd; (count_tmp); pwd;
A partir da documentação oficial do bash :
()
( list )
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.
Como exemplo, considere o seguinte ...
~ # { test_var=test }
~ # echo $test_var
test
~ # ( test_var2=test2 )
~ # echo $test_var2
~ #
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 '()'.
(...)
são usados para executar código em um sub-shell. O código usado bewteen {...}
não será usado em um sub-shell.