89 votes

Quand utiliser () ou {} en bash ?

J'étudie le Shell scripting avec bash et j'ai besoin de connaître la différence entre (...) y {...} . Comment choisir entre les deux lorsqu'on écrit un script ?

106voto

Todd Gamblin Points 101

Si vous voulez que les effets secondaires de la liste de commande affectent votre actuel Shell, utilisez {...}
Si vous voulez vous débarrasser des effets secondaires, utilisez (...)

Par exemple, je pourrais utiliser un subshell si :

  • veulent modifier $IFS pour quelques commandes, mais je ne veux pas modifier $IFS globalement pour le Shell actuel
  • cd quelque part, mais je ne veux pas changer la $PWD pour le Shell actuel

Il 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 restent après la fin de la fonction.

    $ 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 lorsque le sous-shell sort.

    $ cd ; unset files
    $ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
    $ pwd; count_tmp; pwd
    /home/jackman
    11
    /home/jackman
    $ echo "${#files[@]}"
    0

Documentation

31voto

Digital Trauma Points 2316

De l'officiel documentation bash :

()

( list )

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 après la fin du sous-shell.

{}

{ list; }

Placer une liste de commandes entre accolades entraîne l'exécution de la liste dans le contexte actuel de Shell. Aucun sous-shell n'est créé. Le point-virgule (ou la nouvelle ligne) qui suit la liste est obligatoire.

10voto

PeaceByJesus Points 11

Le code figurant dans "{}" est exécuté dans le fil, le processus ou l'environnement actuel et les modifications sont préservées. En d'autres termes, le code est exécuté dans la portée actuelle.
Le code dans '()' est exécuté à l'intérieur d'un processus enfant séparé de bash qui est abandonné après l'exécution. Ce processus enfant est souvent appelé sub-Shell et peut être considéré comme un nouveau processus enfant.

A titre d'exemple, considérez ce qui suit...

 ~ # { test_var=test ; }
 ~ # echo $test_var
 test
 ~ # ( test_var2=test2 )
 ~ # echo $test_var2

 ~ # 

Remarquez que dans le premier exemple avec " {} ", la variable est toujours définie même après le " } " de fermeture, alors que dans l'exemple avec "() ", la variable n'est pas définie en dehors de la portée du "() ".

Notez également la différence de syntaxe entre "{}" et "()". Le délimiteur " ;" est toujours requis pour le code dans '{}', mais pas pour le code dans '()'.

6voto

Antoine Orsoni Points 415

(...) sont utilisés pour exécuter du code dans un sous-Shell. Le code utilisé entre {...} ne sera pas utilisé dans un sous-Shell.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X