Sto studiando script di shell con bash e ho bisogno di sapere la differenza tra (...)
e {...}
. Come si fa a scegliere tra i due quando si scrive una sceneggiatura?
Sto studiando script di shell con bash e ho bisogno di sapere la differenza tra (...)
e {...}
. Come si fa a scegliere tra i due quando si scrive una sceneggiatura?
Risposte:
Se si desidera che gli effetti collaterali dell'elenco dei comandi influiscano sulla shell corrente , utilizzare {...}
Se si desidera eliminare eventuali effetti collaterali, utilizzare(...)
Ad esempio, potrei usare una subshell se:
$IFS
per alcuni comandi, ma non voglio cambiare a $IFS
livello globale per la shell correntecd
da qualche parte, ma non voglio cambiare il $PWD
per la shell correnteVale la pena notare che le parentesi possono essere utilizzate nella definizione di una funzione:
uso normale: parentesi graffe: il corpo della funzione viene eseguito nella shell corrente; gli effetti collaterali rimangono dopo il completamento della funzione
$ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
$ pwd; count_tmp; pwd
/home/jackman
11
/tmp
$ echo "${#files[@]}"
11
uso insolito: parentesi: il corpo della funzione viene eseguito in una subshell; gli effetti collaterali scompaiono quando esce la subshell
$ cd ; unset files
$ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
$ pwd; count_tmp; pwd
/home/jackman
11
/home/jackman
$ echo "${#files[@]}"
0
local
parola chiave aiuta a ripulire l'inquinamento.
pwd; (count_tmp); pwd;
Dalla documentazione ufficiale di bash :
()
( list )
Posizionando un elenco di comandi tra parentesi si crea un ambiente subshell e ciascuno dei comandi nell'elenco viene eseguito in quella subshell. Poiché l'elenco viene eseguito in una subshell, le assegnazioni delle variabili non rimangono attive dopo il completamento della subshell.
{}
{ list; }
Posizionare un elenco di comandi tra parentesi graffe fa sì che l'elenco venga eseguito nel contesto della shell corrente. Non viene creata alcuna subshell. È richiesto il seguente punto e virgola (o newline).
Il codice in "{}" viene eseguito nel thread / processo / ambiente corrente e le modifiche vengono conservate, per dirla in modo più sintetico, il codice viene eseguito nell'ambito corrente.
Il codice in '()' viene eseguito all'interno di un processo figlio separato di bash che viene scartato dopo l'esecuzione. Questo processo figlio viene spesso definito come una sotto-shell e può essere pensato come un nuovo ambito simile a un bambino.
Ad esempio, considerare quanto segue ...
~ # { test_var=test }
~ # echo $test_var
test
~ # ( test_var2=test2 )
~ # echo $test_var2
~ #
Si noti nel primo esempio con '{}' la variabile è ancora impostata anche dopo la chiusura '}', mentre nell'esempio con '()' la variabile non è impostata al di fuori dell'ambito di '()'.
(...)
sono usati per eseguire il codice in una sotto-shell. Il codice usato tra {...}
non verrà usato in una sotto-shell.