Comparatif des variables $* et $@

Utilisation de $* et de $@

Utilisation de $* et de $@

By ronan, 29 novembre, 2011

Les variables $* et $@ contiennent la liste des arguments d'un script shell.
Lorsqu'elles ne sont pas entourées par des guillemets, elles sont équivalentes.

Exemple :

$ nl scr01.sh
     1  #!/bin/bash
     2  cpt=1
     3  echo "Utilisation de la variable \$*"
     4  for arg in $*
     5  do
     6          echo "Argument $cpt : $arg"
     7          ((cpt+=1))
     8  done
     9  cpt=1
    10  echo "Utilisation de la variable \$@"
    11  for arg in $@
    12  do
    13          echo "Argument $cpt : $arg"
    14          ((cpt+=1))
    15  done
    16  exit 0
$ ./scr01.sh a b "c d e" f
Utilisation de la variable $*
Argument 1 : a
Argument 2 : b
Argument 3 : c
Argument 4 : d
Argument 5 : e
Argument 6 : f
Utilisation de la variable $@
Argument 1 : a
Argument 2 : b
Argument 3 : c
Argument 4 : d
Argument 5 : e
Argument 6 : f
$

Interprétation :

  1. $* et $@ contiennent exactement la même liste d'arguments.
  2. Les guillemets protégeant les arguments ne sont pas pris en compte
  3. Ce sont les espaces qui délimitent les arguments

Marc (not verified)

il y a 6 ans

Bonjour Ronan,

Pour être plus précis, et complet, il me semble intéressant d'ajouter que si on met les variables $* et $@ entre guillemets, alors leur comportement n'est plus le même, et les guillemets protégeant les arguments sont pris en compte (du moins pour "$@", pas pour "$*").

$ nl ./scr01.sh
1 #!/bin/bash
2 cpt=1
3 echo "Utilisation de la variable \$*"
4 for arg in $* ; do
5 echo "Argument $cpt : $arg"
6 ((cpt+=1))
7 done
8 cpt=1
9 echo "Utilisation de la variable \$@"
10 for arg in $@ ; do
11 echo "Argument $cpt : $arg"
12 ((cpt+=1))
13 done
14 cpt=1
15 echo "Utilisation de la variable \"\$*\""
16 for arg in "$*" ; do
17 echo "Argument $cpt : $arg"
18 ((cpt+=1))
19 done
20 cpt=1
21 echo "Utilisation de la variable \"\$@\""
22 for arg in "$@" ; do
23 echo "Argument $cpt : $arg"
24 ((cpt+=1))
25 done

$ ./scr01.sh a b "c d e" f
Utilisation de la variable $*
Argument 1 : a
Argument 2 : b
Argument 3 : c
Argument 4 : d
Argument 5 : e
Argument 6 : f
Utilisation de la variable $@
Argument 1 : a
Argument 2 : b
Argument 3 : c
Argument 4 : d
Argument 5 : e
Argument 6 : f
Utilisation de la variable "$*"
Argument 1 : a b c d e f
Utilisation de la variable "$@"
Argument 1 : a
Argument 2 : b
Argument 3 : c d e
Argument 4 : f

Cordialement,

Marc

ronan

il y a 6 ans

In reply to by Marc (not verified)

Tout à fait et c'est justement ce que j'explique sur les deux pages suivantes.

tester (not verified)

il y a 4 ans 10 mois

In reply to by Marc (not verified)

Merci Marc pour ce "$@" qui permet d'avoir un comportement classique de l'éclatement mais évite les soucis des espaces contenus dans les paramètres éventuels de la variante sans guillement.
Il devrait y avoir un paramètre qui permet de désactiver l'utilisation du $@ seul car il me semble être un axe d'attaque possible des scripts l'utilisant pour dévoyer leurs usage si ces paramètres sont à la mains de tiers.

Utilisation de "$*"

Utilisation de "$*"

By ronan, 29 novembre, 2011

Les guillemets autour de $* supprime la signification des espaces contenus dans $*.

Exemple :

$ nl scr02.sh
     1  #!/bin/bash
     2  cpt=1
     3  echo "Utilisation de la variable \"\$*\""
     4  for arg in "$*"
     5  do
     6          echo "Argument $cpt : $arg"
     7          ((cpt+=1))
     8  done
     9  exit 0
$ ./scr02.sh a b c "d e f" g
Utilisation de la variable "$*"
Argument 1 : a b c d e f g
$

Interprétation :

  1. Les guillemets entourant les arguments ne sont pas pris en compte.
  2. Tous les arguments sont considérés comme étant un seul argument.

Utilisation de "$@"

Utilisation de "$@"

By ronan, 29 novembre, 2011

La variable $@ placée entre guillemets permet de conserver la protection des arguments par les guillemets.

Exemple :

$ nl scr03.sh
     1  #!/bin/bash
     2  cpt=1
     3  echo "Utilisation de la variable \"\$@\""
     4  for arg in "$@"
     5  do
     6          echo "Argument $cpt : $arg"
     7          ((cpt+=1))
     8  done
     9  exit 0
$ ./scr03.sh a b c "d e f" g
Utilisation de la variable "$@"
Argument 1 : a
Argument 2 : b
Argument 3 : c
Argument 4 : d e f
Argument 5 : g
$

Interprétation :

  1. Les espaces délimitent la liste des arguments.
  2. Les arguments placés entre guillemets sont considérés comme étant un seul argument