eval
prend une chaîne de caractères comme argument, et l'évalue comme si vous aviez tapé cette chaîne sur une ligne de commande. (Si vous passez plusieurs arguments, ils sont d'abord rejoint avec des espaces entre eux.)
${$n}
est une erreur de syntaxe bash. Entre les accolades, vous ne pouvez avoir un nom de variable, avec quelques préfixes et des suffixes, mais vous ne pouvez pas avoir d'arbitraire bash syntaxe et, en particulier, vous ne pouvez pas utiliser la variable d'expansion. Il y a une façon de dire "la valeur de la variable dont le nom est dans cette variable", mais:
echo ${!n}
one
$(…)
exécute la commande spécifiée à l'intérieur des parenthèses dans un shell interne est exécuté (c'est à dire dans un processus distinct qui hérite de tous les paramètres tels que les valeurs des variables du shell courant), et regroupe de sa sortie. Donc, echo $($n)
s'exécute $n
comme une commande shell, et affiche sa sortie. Depuis $n
évalue 1
, $($n)
tente d'exécuter la commande 1
, ce qui n'existe pas.
eval echo \${$n}
exécute les paramètres passés à l' eval
. Après l'expansion, les paramètres sont echo
et ${1}
. Donc, eval echo \${$n}
exécute la commande echo ${1}
.
Notez que la plupart du temps, vous devez utiliser des guillemets autour de la variable de substitution et de commande susbtitutions (c'est à dire quand il y a un $
): "$foo", "$(foo)"
. Toujours mettre des guillemets autour de la variable de commande et de substitution, sauf si vous savez que vous devez les laisser hors tension. Sans les guillemets, le shell exécute domaine de fractionnement (c'est à dire, il se divise la valeur de la variable ou le résultat de la commande en mots distincts), puis traite chaque mot comme un modèle générique. Par exemple:
$ ls
file1 file2 otherfile
$ set -- 'f* *'
$ echo "$1"
f* *
$ echo $1
file1 file2 file1 file2 otherfile
$ n=1
$ eval echo \${$n}
file1 file2 file1 file2 otherfile
$eval echo \"\${$n}\"
f* *
$ echo "${!n}"
f* *
eval
n'est pas utilisé très souvent. Dans quelques coquilles, l'utilisation la plus courante est d'obtenir la valeur d'une variable dont le nom n'est pas connu avant l'exécution. En bash, ce n'est pas nécessaire grâce à l' ${!VAR}
de la syntaxe. eval
est toujours utile lorsque vous avez besoin de construire plus de commande contenant des opérateurs, des mots réservés, etc.