J'étudie les scripts shell avec bash et j'ai besoin de connaître la différence entre (...)
et {...}
. Comment peut-on choisir entre les deux lors de l'écriture d'un script?
J'étudie les scripts shell avec bash et j'ai besoin de connaître la différence entre (...)
et {...}
. Comment peut-on choisir entre les deux lors de l'écriture d'un script?
Réponses:
Si vous souhaitez que les effets secondaires de la liste de commandes affectent votre shell actuel , utilisez {...}
Si vous souhaitez supprimer tout effet secondaire, utilisez(...)
Par exemple, je pourrais utiliser un sous-shell si je:
$IFS
quelques commandes, mais je ne veux pas modifier $IFS
globalement le shell actuelcd
quelque part, mais je ne veux pas changer le $PWD
pour le shell actuelIl est intéressant de noter que les parenthèses peuvent être utilisées dans une définition de fonction:
utilisation normale: accolades: le corps de la fonction s'exécute dans le shell actuel; les effets secondaires persistent une fois la fonction terminée
$ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
$ pwd; count_tmp; pwd
/home/jackman
11
/tmp
$ echo "${#files[@]}"
11
utilisation inhabituelle: parenthèses: le corps de la fonction s'exécute dans un sous-shell; les effets secondaires disparaissent à la sortie du sous-shell
$ cd ; unset files
$ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
$ pwd; count_tmp; pwd
/home/jackman
11
/home/jackman
$ echo "${#files[@]}"
0
local
mot clé contribue largement à réduire cette pollution.
pwd; (count_tmp); pwd;
De la documentation officielle de bash :
()
( list )
Le fait de placer une liste de commandes entre parenthèses entraîne la création d’un environnement de sous-shell et l’exécution de chacune des commandes de la liste dans ce sous-shell. Comme la liste est exécutée dans un sous-shell, les affectations de variables ne restent pas en vigueur une fois le sous-shell terminé.
{}
{ list; }
Si vous placez une liste de commandes entre des accolades, la liste sera exécutée dans le contexte actuel du shell. Aucun sous-shell n'est créé. La liste suivante point-virgule (ou nouvelle ligne) est requise.
Le code dans '{}' est exécuté dans le thread / processus / environnement actuel et les modifications sont conservées. Pour le dire plus succinctement, le code est exécuté dans la portée actuelle.
Le code dans '()' est exécuté dans un processus enfant distinct de bash qui est ignoré après exécution. Ce processus enfant est souvent appelé un sous-shell et peut être considéré comme un nouveau domaine d'application semblable à celui d'un enfant.
A titre d'exemple, considérons ce qui suit ...
~ # { test_var=test }
~ # echo $test_var
test
~ # ( test_var2=test2 )
~ # echo $test_var2
~ #
Notez que dans le premier exemple avec '{}', la variable est toujours définie même après la fermeture '}', alors que dans l'exemple avec '()', la variable n'est pas définie en dehors de la portée de '()'.
(...)
sont utilisés pour exécuter du code dans un sous-shell. Le code utilisé {...}
avant ne sera pas utilisé dans un sous-shell.