Comment utiliser des crochets doubles ou simples, des parenthèses, des accolades

Je suis confus par l'utilisation des parenthèses, des parenthèses, des accolades dans Bash, ainsi que par la différence entre leurs formes doubles ou simples. Est-il une explication claire?

574
demandé sur codeforester 2010-02-03 01:22:54

6 réponses

Dans Bash, test et [ sont les builtins.

Le support double permet des fonctionnalités supplémentaires. Par exemple, vous pouvez utiliser && et || au lieu de -a et -o et il y a un opérateur de correspondance d'expression régulière =~.

Les accolades, en plus de délimiter un nom de variable, sont utilisées pour l'expansion des paramètres afin que vous puissiez faire des choses comme:

  • Tronquer le contenu d'un la variable

    $ var="abcde"; echo ${var%d*}
    abc

  • Faire des substitutions similaires à sed

    $ var="abcde"; echo ${var/de/12}
    abc12

  • Utiliser une valeur par défaut

    $ default="hello"; unset var; echo ${var:-$default}
    hello

  • Et plusieurs autres

En outre, les extensions d'accolades créent des listes de chaînes qui sont généralement itérées dans des boucles:

$ echo f{oo,ee,a}d
food feed fad

$ mv error.log{,.OLD}
(error.log is renamed to error.log.OLD because the brace expression
expands to "mv error.log error.log.OLD")

$ for num in {000..2}; do echo "$num"; done
000
001
002

$ echo {00..8..2}
00 02 04 06 08

$ echo {D..T..4}
D H L P T

Notez que les fonctionnalités de zéro et d'incrément n'étaient pas disponibles avant Bash 4.

Merci à gboffi pour me rappeler les extensions de brace.

Double parenthèses sont utilisées pour opérations arithmétiques:

((a++))

((meaning = 42))

for ((i=0; i<10; i++))

echo $((a + b + (14 * c)))

Et ils vous permettent d'omettre les signes dollar sur les variables integer et array et d'inclure des espaces autour des opérateurs pour plus de lisibilité.

Les crochets simples sont également utilisés pour les indices array :

array[4]="hello"

element=${array[index]}

Accolade bouclés sont nécessaires pour (la plupart / tous?) références de tableau sur le côté droit.

Commentaire de Ephemient m'a rappelé que les parenthèses sont également utilisées pour les sous-coquilles. Et qu'ils sont utilisés pour créer des tableaux.

array=(1 2 3)
echo ${array[1]}
2
525
répondu Dennis Williamson 2014-10-24 15:12:07
  1. Un seul support ([) habituellement appelle effectivement un programme nommé [; man test ou man [ pour plus d'info. Exemple:

    $ VARIABLE=abcdef
    $ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi
    yes
    
  2. Le double support ([[) fait la même chose (fondamentalement) comme un seul support, mais est un bash intégré.

    $ VARIABLE=abcdef
    $ if [[ $VARIABLE == 123456 ]] ; then echo yes ; else echo no ; fi
    no
    
  3. Les parenthèses (()) sont utilisées pour créer un sous-shell. Par exemple:

    $ pwd
    /home/user 
    $ (cd /tmp; pwd)
    /tmp
    $ pwd
    /home/user
    

    Comme vous pouvez le voir, le sous-shell vous a permis d'effectuer des opérations sans affecter l'environnement du shell actuel.

4a. les accolades ({}) sont utilisées pour identifier sans ambiguïté les variables. Exemple:

    $ VARIABLE=abcdef
    $ echo Variable: $VARIABLE
    Variable: abcdef
    $ echo Variable: $VARIABLE123456
    Variable:
    $ echo Variable: ${VARIABLE}123456
    Variable: abcdef123456

4b. les accolades sont également utilisées pour exécuter une séquence de commandes dans le contexte shell actuel , par exemple

    $ { date; top -b -n1 | head ; } >logfile 
    # 'date' and 'top' output are concatenated, 
    # could be useful sometimes to hunt for a top loader )

    $ { date; make 2>&1; date; } | tee logfile
    # now we can calculate the duration of a build from the logfile

Il y a une différence syntaxique subtile avec ( ), cependant (voir référence bash ); essentiellement, un point-virgule ; après la dernière commande dans les accolades est un must, et les accolades {, } doit être entouré par des espaces.

292
répondu Carl Norum 2012-07-16 20:00:11

Crochets

if [ CONDITION ]    Test construct  
if [[ CONDITION ]]  Extended test construct  
Array[1]=element1   Array initialization  
[a-z]               Range of characters within a Regular Expression
$[ expression ]     A non-standard & obsolete version of $(( expression )) [1]

[1] http://wiki.bash-hackers.org/scripting/obsolete

Accolades

${variable}                             Parameter substitution  
${!variable}                            Indirect variable reference  
{ command1; command2; . . . commandN; } Block of code  
{string1,string2,string3,...}           Brace expansion  
{a..z}                                  Extended brace expansion  
{}                                      Text replacement, after find and xargs

Les Parenthèses

( command1; command2 )             Command group executed within a subshell  
Array=(element1 element2 element3) Array initialization  
result=$(COMMAND)                  Command substitution, new style  
>(COMMAND)                         Process substitution  
<(COMMAND)                         Process substitution 

Des Doubles Parenthèses

(( var = 78 ))            Integer arithmetic   
var=$(( 20 + 5 ))         Integer arithmetic, with variable assignment   
(( var++ ))               C-style variable increment   
(( var-- ))               C-style variable decrement   
(( var0 = var1<98?9:21 )) C-style ternary operation
258
répondu Yola 2016-06-19 15:41:33

Je voulais juste les ajouter à partir de TLDP :

~:$ echo $SHELL
/bin/bash

~:$ echo ${#SHELL}
9

~:$ ARRAY=(one two three)

~:$ echo ${#ARRAY}
3

~:$ echo ${TEST:-test}
test

~:$ echo $TEST


~:$ export TEST=a_string

~:$ echo ${TEST:-test}
a_string

~:$ echo ${TEST2:-$TEST}
a_string

~:$ echo $TEST2


~:$ echo ${TEST2:=$TEST}
a_string

~:$ echo $TEST2
a_string

~:$ export STRING="thisisaverylongname"

~:$ echo ${STRING:4}
isaverylongname

~:$ echo ${STRING:6:5}
avery

~:$ echo ${ARRAY[*]}
one two one three one four

~:$ echo ${ARRAY[*]#one}
two three four

~:$ echo ${ARRAY[*]#t}
one wo one hree one four

~:$ echo ${ARRAY[*]#t*}
one wo one hree one four

~:$ echo ${ARRAY[*]##t*}
one one one four

~:$ echo $STRING
thisisaverylongname

~:$ echo ${STRING%name}
thisisaverylong

~:$ echo ${STRING/name/string}
thisisaverylongstring
20
répondu kzh 2010-06-29 17:40:42

La différence entre test, [ et [[ est expliqué en détails dans le BashFAQ.

Pour faire court: test implémente l'ancienne syntaxe portable de commande. Dans presque toutes les coquilles (les plus anciennes coquilles de Bourne sont les exception), [est un synonyme de test (mais nécessite un argument final de ]). Bien que tous les shells modernes aient des implémentations intégrées de [, il y a généralement encore un exécutable externe de ce nom, par exemple /bac/[.

[[ est une nouvelle version améliorée, ce qui est un mot-clé, pas un programme. Cela a des effets bénéfiques sur la facilité d'utilisation, comme indiqué ci-dessous. [[ être compris par KornShell et BASH (par exemple 2.03), mais pas par les anciens POSIX ou BourneShell.

Et la conclusion:

Quand la nouvelle commande de test [[ doit-elle être utilisée, et quand l'ancienne [? Si la portabilité vers le BourneShell est une préoccupation, l'ancienne syntaxe devrait être utilisé. Si, d'autre part le script nécessite BASH ou KornShell, la nouvelle syntaxe est beaucoup plus souple.

17
répondu fwhacking 2011-10-28 09:22:51

Parenthèses dans la définition de la fonction

Les parenthèses {[2] } sont utilisées dans la définition de la fonction:

function_name () { command1 ; command2 ; }

C'est la raison pour laquelle vous devez échapper les parenthèses même dans les paramètres de commande:

$ echo (
bash: syntax error near unexpected token `newline'

$ echo \(
(

$ echo () { command echo The command echo was redefined. ; }
$ echo anything
The command echo was redefined.
16
répondu pabouk 2013-09-09 08:56:19