GNU/Linux >> Tutoriels Linux >  >> Linux

commande eval dans Bash et ses utilisations typiques

eval prend une chaîne 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 joints par des espaces entre eux.)

${$n} est une erreur de syntaxe dans bash. À l'intérieur des accolades, vous ne pouvez avoir qu'un nom de variable, avec quelques préfixes et suffixes possibles, mais vous ne pouvez pas avoir de syntaxe bash arbitraire et en particulier vous ne pouvez pas utiliser l'expansion de variable. Il y a une façon de dire "la valeur de la variable dont le nom est dans cette variable", cependant :

echo ${!n}
one

$(…) exécute la commande spécifiée entre parenthèses dans un sous-shell (c'est-à-dire dans un processus séparé qui hérite de tous les paramètres tels que les valeurs des variables du shell actuel) et rassemble sa sortie. Alors echo $($n) exécute $n comme une commande shell et affiche sa sortie. Depuis $n évalue à 1 , $($n) tente d'exécuter la commande 1 , qui n'existe pas.

eval echo \${$n} exécute les paramètres passés à eval . Après 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 des substitutions de variables et des substitutions de commandes (c'est-à-dire chaque fois qu'il y a un $ ) :"$foo", "$(foo)" . Mettez toujours des guillemets doubles autour des substitutions de variables et de commandes , sauf si vous savez que vous devez les laisser désactivés. Sans les guillemets doubles, le shell effectue le fractionnement des champs (c'est-à-dire qu'il divise la valeur de la variable ou la sortie de la commande en mots séparés), puis traite chaque mot comme un motif 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 certains shells, l'utilisation la plus courante consiste à obtenir la valeur d'une variable dont le nom n'est connu qu'à l'exécution. En bash, ce n'est pas nécessaire grâce au ${!VAR} syntaxe. eval est toujours utile lorsque vous devez construire une commande plus longue contenant des opérateurs, des mots réservés, etc.


Pensez simplement à eval comme "évaluer votre expression une fois de plus avant l'exécution"

eval echo \${$n} devient echo $1 après le premier tour d'évaluation. Trois changements à noter :

  • Le \$ est devenu $ (La barre oblique inverse est nécessaire, sinon il essaie d'évaluer ${$n} , ce qui signifie une variable nommée {$n} , ce qui n'est pas autorisé)
  • $n a été évalué à 1
  • Le eval disparu

Au second tour, c'est essentiellement echo $1 qui peut être directement exécuté.

Alors eval <some command> évaluera d'abord <some command> (par évaluer ici, je veux dire remplacer les variables, remplacer les caractères échappés par les bons, etc.), puis exécuter à nouveau l'expression résultante.

eval est utilisé lorsque vous souhaitez créer dynamiquement des variables ou lire les sorties de programmes spécifiquement conçus pour être lus comme ceci. Voir http://mywiki.wooledge.org/BashFAQ/048 pour des exemples. Le lien contient également quelques façons typiques dont eval est utilisé et les risques qui y sont associés.


D'après mon expérience, une utilisation "typique" d'eval consiste à exécuter des commandes qui génèrent des commandes shell pour définir des variables d'environnement.

Peut-être avez-vous un système qui utilise une collection de variables d'environnement, et vous avez un script ou un programme qui détermine celles qui doivent être définies et leurs valeurs. Chaque fois que vous exécutez un script ou un programme, il s'exécute dans un processus forké, de sorte que tout ce qu'il fait directement aux variables d'environnement est perdu lorsqu'il se termine. Mais ce script ou programme peut envoyer les commandes d'exportation vers stdout.

Sans eval, vous auriez besoin de rediriger stdout vers un fichier temporaire, de sourcer le fichier temporaire, puis de le supprimer. Avec eval, vous pouvez simplement :

eval "$(script-or-program)"

Notez que les guillemets sont importants. Prenons cet exemple (artificiel) :

# activate.sh
echo 'I got activated!'

# test.py
print("export foo=bar/baz/womp")
print(". activate.sh")

$ eval $(python test.py)
bash: export: `.': not a valid identifier
bash: export: `activate.sh': not a valid identifier
$ eval "$(python test.py)"
I got activated!

Linux
  1. La commande "eval" dans Bash ?

  2. commande d'exportation bash

  3. Pourquoi eval devrait-il être évité dans Bash et que dois-je utiliser à la place ?

  4. Bash - Commande de date et espace

  5. Quelle est la différence entre &> et >&en bash ?

Commande de source bash

Commande d'historique sous Linux (historique de bash)

Commande de sortie Bash et codes de sortie

Commande Bash printf

Comment lire la sortie et les utilisations de la commande Linux Top

Script bash (II)