Que pouvez-vous faire avec la evalcommande? Pourquoi est-ce utile? Est-ce une sorte de fonction intégrée dans bash? Il n'y a pas de manpage pour cela ..
Utilisez type commandpour savoir de quel type est une commande . ( type evaldans ce cas)
rozcietrzewiacz
9
"eval est un shell construit"
Nuno Rafael Figueiredo
3
help evalobtenir la page "man" de votre shell
m-ric
eval est intégré à bash et est documenté dans la page de manuel de bash. Il suffit donc de taper "man bash" et de rechercher la section appropriée pour eval. Ceci s’applique également aux autres commandes intégrées de bash.
Dirk Thannhäuser
Réponses:
132
evalfait partie de POSIX. C'est une interface qui peut être un shell intégré.
Dans la première ligne, vous définissez $fooavec la valeur '10'et $xavec la valeur 'foo'.
Définissez maintenant $y, qui consiste en la chaîne '$foo'. Le signe dollar doit être échappé avec '$'.
Pour vérifier le résultat, echo $y.
Le résultat sera la chaîne '$foo'
Maintenant, nous répétons la mission avec eval. Il va d'abord évaluer $xà la chaîne 'foo'. Nous avons maintenant la déclaration y=$fooqui sera évaluée y=10.
Le résultat de echo $yest maintenant la valeur '10'.
C'est une fonction courante dans de nombreuses langues, par exemple Perl et JavaScript. Consultez perldoc eval pour plus d'exemples: http://perldoc.perl.org/functions/eval.html
Dans la terminologie du shell, evalest une fonction intégrée, pas une fonction. En pratique, les fonctions intégrées se comportent beaucoup comme des fonctions qui n'ont pas de définition dans le langage, mais pas tout à fait (comme cela apparaît si vous êtes assez tordu pour définir une fonction appelée eval).
Gilles
merci, corrigé que :-)
echox
4
Quelle est la difference entre eval et backticks `?
JohnyTex
5
Les backticks sont un raccourci pour l'exécution d'un autre shell entier, ce qui signifie que vous aurez un autre processus enfant bash / sh en cours d'exécution dans votre script.
Aaron R.
Pourquoi echo $ y (stage 3) ramène foo (10) au lieu de $ foo? (c'est-à-dire juste la valeur de foo au lieu de la chaîne $ + la valeur de foo)?
JohnDoea
60
Oui, evalest une commande interne bash, elle est donc décrite dans la bashpage de manuel.
eval[arg ...]The args are read and concatenated together into a single com-
mand.This command is then read and executed by the shell, and
its exit status is returned as the value of eval.If there are
no args, or only null arguments,eval returns 0.
Il est généralement utilisé en combinaison avec une substitution de commande . Sans explicite eval, le shell tente d' exécuter le résultat d'une substitution de commande et non de l' évaluer .
Dites que vous voulez coder un équivalent de VAR=value; echo $VAR. Notez la différence dans la façon dont le shell traite les écrits de echo VAR=value:
andcoz@...:~> $( echo VAR=value )
bash: VAR=value: command not found
andcoz@...:~> echo $VAR<empty line>
Le shell tente de s’exécuter echoet VAR=valuesous forme de deux commandes distinctes. Cela renvoie une erreur à propos de la deuxième chaîne. La mission reste inefficace.
andcoz@...:~>eval $( echo VAR=value )
andcoz@...:~> echo $VAR
value
Le shell fusionne (concatène) les deux chaînes echoet VAR=valueanalyse cette unité en fonction de règles appropriées et l'exécute.
Last but not least, evalpeut être une commande très dangereuse. Toute entrée dans une evalcommande doit être soigneusement vérifiée pour éviter les problèmes de sécurité.
evaln'a pas de page de manuel car ce n'est pas une commande externe séparée, mais plutôt un shell intégré, c'est-à-dire une commande interne à et connue uniquement du shell ( bash). La partie pertinente de la bashpage de manuel dit:
eval[arg ...]The args are read and concatenated together into a single command.This command is then read and executed by the shell, and its exit
status is returned as the value of eval.If there are no args, or only
null arguments,eval returns 0
De plus, la sortie if help evalest:
eval:eval[arg ...]Execute arguments as a shell command.CombineARGs into a single string, use the result as input to the shell,
and execute the resulting commands.ExitStatus:Returns exit status of command or success if command is null.
evalC’est une commande puissante et si vous avez l’intention de l’utiliser, vous devez faire très attention à ne pas risquer de compromettre la sécurité .
L'instruction eval indique au shell de prendre les arguments de eval en tant que commande et de les exécuter via la ligne de commande. C'est utile dans une situation comme celle ci-dessous:
Dans votre script, si vous définissez une commande dans une variable et que vous souhaitez utiliser cette commande ultérieurement, vous devez utiliser eval:
/home/user1 > a="ls | more"/home/user1 > $a
bash: command not found: ls | more/home/user1 ># Above command didn't work as ls tried to list file with name pipe (|) and more. But these files are not there/home/user1 >eval $a
file.txt
mailids
remote_cmd.sh
sample.txt
tmp/home/user1 >
Le commentaire de la ligne 4 de votre exemple est incorrect: "La commande ci-dessus n'a pas fonctionné car bash a tenté de trouver une commande appelée ls | more. En d'autres termes, le nom de la commande unique était composé de neuf caractères, espaces et symbole de tuyau compris. .
tpi
J'ai exactement le même comportement qu'il a rapporté. bash --version == GNU bash, version 3.2.57 (1) -release (x86_64-apple-darwin18)
Alexander Bird
10
Eval c'est quoi?
eval est une commande shell généralement implémentée.
Le terme "intégré" implique que le shell peut exécuter l'utilitaire directement et n'a pas besoin de le rechercher.
Qu'est ce que ça fait?
En termes simples: crée une ligne d’entrée à analyser deux fois .
Comment ça fait ça?
Le shell a une séquence d'étapes à suivre pour "traiter" une ligne. Vous pouvez regarder cette image et vous rendre compte que eval est la seule ligne qui monte vers la première étape, à gauche. De la description POSIX :
2.1 Introduction de Shell
Le shell lit son entrée ....
Le shell décompose l'entrée en jetons: mots et opérateurs
Le shell analyse les entrées en commandes simples et composées.
Le shell effectue diverses extensions (séparément) ...
Le shell effectue la redirection et supprime les opérateurs de redirection et leurs opérandes de la liste des paramètres.
Le shell exécute une fonction, un fichier intégré, un fichier exécutable ou un script ...
Le shell attend éventuellement que la commande soit terminée et recueille le statut de sortie.
A l'étape 6, une commande intégrée sera exécutée.
À l'étape 6, eval renvoie la ligne traitée à l'étape 1.
Il s'agit de la seule condition dans laquelle la séquence d'exécution revient.
C'est pourquoi je dis: Avec eval, une ligne d'entrée est analysée deux fois .
Effets de l'analyse deux fois.
La première.
Et l'effet le plus important à comprendre. Est - ce une conséquence de la première fois qu'une ligne est soumise aux sept étapes shell ci - dessus, est cite . À l'étape 4 (extensions), il y a également une séquence d'étapes pour effectuer toutes les extensions , dont la dernière est la suppression des devis :
Le retrait des devis doit toujours être effectué en dernier.
Donc, toujours, il y a un niveau de cotation supprimé.
Seconde.
En conséquence de ce premier effet, des parties supplémentaires / différentes de la ligne sont exposées à l'analyse syntaxique du shell et à toutes les autres étapes.
Exemple.
Indirection.
Cela permet d’exécuter des extensions indirectes:
a=b b=c ;eval echo \$$a ### shall produce "c"
Pourquoi? Parce que sur la première boucle, la première $est citée.
En tant que tel, il est ignoré pour les extensions du shell.
Le prochain $avec le nom a est développé pour produire "b".
Ensuite, un niveau de citation est supprimé, ce qui rend le premier $non cité .
Fin de la première boucle.
C'est ensuite sur la seconde boucle que la chaîne $best lue par le shell.
Puis étendu à "c"
et donné comme argument à echo.
Pour "voir" ce que eval produira sur la première boucle (à réévaluer), utilisez echo. Ou toute commande / script / programme qui montre clairement les arguments:
$ a=b b=c
$ eval echo \$$a;
c
Remplacez eval par echo pour "voir" ce qui se passe:
$ echo echo \$$a
echo $b
Il est également possible d'afficher toutes les "parties" d'une ligne avec:
$ printf '<%s> ' echo \$$a<echo><$b>
Dans cet exemple, il ne s'agit que d'un écho et d'une variable, mais souvenez-vous-en pour vous aider à évaluer des cas plus complexes.
Une correction
Il faut dire que: il y a une erreur dans le code ci-dessus, pouvez-vous le voir?.
Facile: il manque des citations.
Comment? tu peux demander. Simple, changeons les variables (pas le code):
$ a=b b="hi jk"
$ eval echo \$$a
hi jk
Voir les espaces manquants?
C'est parce que la valeur à l'intérieur a $bété divisée par le shell.
Si cela ne vous convainc pas, essayez ceci:
$ a=b b="hi * jk"
$ eval echo \$$a ### warning this will expand to the list ### of all files in the present directory.
Pourquoi?
Citations manquantes. Pour que cela fonctionne correctement (ajoutez "$a"des \"devis internes et externes ).
Essayez ceci (est parfaitement sûr):
$ a=b b="hi * jk"
$ eval echo \" \$"$a" \"
hi * jk
A propos du manuel:
Il n'y a pas de page de manuel pour cela ..
Non, il n'y a pas de page de manuel indépendante pour cela. La recherche de manuel avec man -f evalou même apropos evalne montre aucune entrée.
Il est inclus à l'intérieur man bash. Comme est intégré.
Recherchez "SHELL BUILTIN COMMANDS" puis "eval".
Un moyen plus simple d’obtenir de l’aide est le suivant: Dans bash, vous pouvez help evalvoir l’aide de la fonction intégrée.
Pourquoi eval est-il appelé le mal?
Parce qu'il s'agit d'un texte contraignant à coder de manière dynamique.
En d'autres termes: il convertit la liste de ses arguments (et / ou développements de tels arguments) en une ligne exécutée. Si, pour une raison quelconque, un argument a été défini par un attaquant, vous allez exécuter du code d’attaquant.
Ou encore plus simplement, avec eval, vous indiquez à quiconque a défini la valeur d'un ou plusieurs arguments:
Allez, assieds-toi ici et tape n'importe quelle ligne de commande, je l'exécuterai avec mes pouvoirs.
Est-ce dangereux? Cela devrait être clair pour tout le monde.
La règle de sécurité pour eval devrait être:
N'exécutez eval que sur les variables auxquelles vous avez attribué sa valeur.
evalest une caractéristique des langues les plus interprétées ( TCL, python, ruby...), non seulement des coquilles. Il est utilisé pour évaluer le code de manière dynamique.
Dans les shells, il est implémenté en tant que commande intégrée au shell.
Fondamentalement, evalprend une chaîne en tant qu'argument et évalue / interprète le code qu'il contient. Dans les shells, evalpeut prendre plus d'un argument, mais il evalsuffit de les concaténer pour former la chaîne à évaluer.
C'est très puissant car vous pouvez construire du code de manière dynamique et l'exécuter, chose que vous ne pouvez pas faire dans des langages compilés comme C.
Comme:
varname=$1 varvalue=$2eval"$varname=\$varvalue"# evaluate a string like "foo=$varvalue"# which in Bourne-like shell language# is a variable assignment.
Mais c’est aussi dangereux, car il est important de nettoyer les parties dynamiques (fournies de l’extérieur) de ce qui est transféré evalcar elles sont interprétées comme du code shell.
Par exemple, ci-dessus, si $1est evil-command; var, evalfinirait par évaluer le evil-command; var=$varvaluecode shell et ensuite l'exécuter evil-command.
La perversité de evalest souvent exagérée.
OK, c'est dangereux, mais au moins on sait que c'est dangereux.
Beaucoup d'autres commandes évaluera le code shell dans ses arguments , sinon aseptisé, comme ( en fonction de la coquille), [alias test, export, printf, GNU sed, awket bien sûr sh/ bash/ perlet tous les interprètes ...
Des exemples (ici en utilisant unamecomme evil-commandet $aen externe fourni des données hygiénisées):
Ces commandes sed, export... pourraient être considérées comme plus dangereuses car, même si c'est évident eval "$var", le contenu de $varsera évalué en tant que code shell, ce n'est pas si évident avec sed "s/foo/$var/"ou export "$var=value"ou [ "$var" -gt 0 ]. La dangerosité est la même, mais elle est dissimulée dans ces autres commandes.
@BinaryZebra, c'est sedcomme si evalon passait une chaîne contenue dans une variable, et pour les deux, le contenu de cette chaîne finit par être évalué en tant que code shell, donc sedc'est aussi dangereux que eval, c'est ce que je dis. sedest en train de passer une chaîne contenant uname(uname n’a pas encore été exécuté) et par l’appel de sed, la commande uname est exécutée. J'aime pour eval. En fait sed 's/foo/$a/g', vous ne transmettez pas de données non normalisées à sed, ce n'est pas ce dont nous parlons ici.
Merci pour votre contribution, mais, aussi divertissants qu’ils soient, nous ne sommes pas intéressés par la compilation d’une liste d’exemples (légèrement différents) d’utilisation eval. Pensez-vous que certains aspects fondamentaux et critiques de la fonctionnalité evalne sont pas abordés dans les réponses existantes? Si oui, expliquez -le et utilisez l'exemple pour illustrer votre explication. S'il vous plaît ne répondez pas dans les commentaires; éditez votre réponse pour la rendre plus claire et plus complète.
type command
pour savoir de quel type est une commande . (type eval
dans ce cas)help eval
obtenir la page "man" de votre shellRéponses:
eval
fait partie de POSIX. C'est une interface qui peut être un shell intégré.Son décrit dans le "Manuel du programmeur POSIX": http://www.unix.com/man-page/posix/1posix/eval/
Il faudra un argument et en construit une commande, qui sera exécutée par le shell. Voici l'exemple de la page de manuel:
$foo
avec la valeur'10'
et$x
avec la valeur'foo'
.$y
, qui consiste en la chaîne'$foo'
. Le signe dollar doit être échappé avec'$'
.echo $y
.'$foo'
eval
. Il va d'abord évaluer$x
à la chaîne'foo'
. Nous avons maintenant la déclarationy=$foo
qui sera évaluéey=10
.echo $y
est maintenant la valeur'10'
.C'est une fonction courante dans de nombreuses langues, par exemple Perl et JavaScript. Consultez perldoc eval pour plus d'exemples: http://perldoc.perl.org/functions/eval.html
la source
eval
est une fonction intégrée, pas une fonction. En pratique, les fonctions intégrées se comportent beaucoup comme des fonctions qui n'ont pas de définition dans le langage, mais pas tout à fait (comme cela apparaît si vous êtes assez tordu pour définir une fonction appeléeeval
).Oui,
eval
est une commande interne bash, elle est donc décrite dans labash
page de manuel.Il est généralement utilisé en combinaison avec une substitution de commande . Sans explicite
eval
, le shell tente d' exécuter le résultat d'une substitution de commande et non de l' évaluer .Dites que vous voulez coder un équivalent de
VAR=value; echo $VAR
. Notez la différence dans la façon dont le shell traite les écrits deecho VAR=value
:Le shell tente de s’exécuter
echo
etVAR=value
sous forme de deux commandes distinctes. Cela renvoie une erreur à propos de la deuxième chaîne. La mission reste inefficace.echo
etVAR=value
analyse cette unité en fonction de règles appropriées et l'exécute.Last but not least,
eval
peut être une commande très dangereuse. Toute entrée dans uneeval
commande doit être soigneusement vérifiée pour éviter les problèmes de sécurité.la source
eval
n'a pas de page de manuel car ce n'est pas une commande externe séparée, mais plutôt un shell intégré, c'est-à-dire une commande interne à et connue uniquement du shell (bash
). La partie pertinente de labash
page de manuel dit:De plus, la sortie if
help eval
est:eval
C’est une commande puissante et si vous avez l’intention de l’utiliser, vous devez faire très attention à ne pas risquer de compromettre la sécurité .la source
L'instruction eval indique au shell de prendre les arguments de eval en tant que commande et de les exécuter via la ligne de commande. C'est utile dans une situation comme celle ci-dessous:
Dans votre script, si vous définissez une commande dans une variable et que vous souhaitez utiliser cette commande ultérieurement, vous devez utiliser eval:
la source
ls | more
. En d'autres termes, le nom de la commande unique était composé de neuf caractères, espaces et symbole de tuyau compris. .Eval c'est quoi?
eval est une commande shell généralement implémentée.
Dans POSIX, il est répertorié dans "2.14. Utilitaires intégrés spéciaux" à l’entrée "eval" .
Ce qui est construit signifie:
Qu'est ce que ça fait?
En termes simples: crée une ligne d’entrée à analyser deux fois .
Comment ça fait ça?
Le shell a une séquence d'étapes à suivre pour "traiter" une ligne. Vous pouvez regarder cette image et vous rendre compte que eval est la seule ligne qui monte vers la première étape, à gauche. De la description POSIX :
A l'étape 6, une commande intégrée sera exécutée.
À l'étape 6, eval renvoie la ligne traitée à l'étape 1.
Il s'agit de la seule condition dans laquelle la séquence d'exécution revient.
Effets de l'analyse deux fois.
La première.
Et l'effet le plus important à comprendre. Est - ce une conséquence de la première fois qu'une ligne est soumise aux sept étapes shell ci - dessus, est cite . À l'étape 4 (extensions), il y a également une séquence d'étapes pour effectuer toutes les extensions , dont la dernière est la suppression des devis :
Donc, toujours, il y a un niveau de cotation supprimé.
Seconde.
En conséquence de ce premier effet, des parties supplémentaires / différentes de la ligne sont exposées à l'analyse syntaxique du shell et à toutes les autres étapes.
Exemple.
Indirection.
Cela permet d’exécuter des extensions indirectes:
Pourquoi? Parce que sur la première boucle, la première
$
est citée.En tant que tel, il est ignoré pour les extensions du shell.
Le prochain
$
avec le nom a est développé pour produire "b".Ensuite, un niveau de citation est supprimé, ce qui rend le premier
$
non cité .Fin de la première boucle.
C'est ensuite sur la seconde boucle que la chaîne
$b
est lue par le shell.Puis étendu à "c"
et donné comme argument à
echo
.Pour "voir" ce que eval produira sur la première boucle (à réévaluer), utilisez echo. Ou toute commande / script / programme qui montre clairement les arguments:
Remplacez eval par echo pour "voir" ce qui se passe:
Il est également possible d'afficher toutes les "parties" d'une ligne avec:
Dans cet exemple, il ne s'agit que d'un écho et d'une variable, mais souvenez-vous-en pour vous aider à évaluer des cas plus complexes.
Une correction
Il faut dire que: il y a une erreur dans le code ci-dessus, pouvez-vous le voir?.
Facile: il manque des citations.
Comment? tu peux demander. Simple, changeons les variables (pas le code):
Voir les espaces manquants?
C'est parce que la valeur à l'intérieur a
$b
été divisée par le shell.Si cela ne vous convainc pas, essayez ceci:
Pourquoi?
Citations manquantes. Pour que cela fonctionne correctement (ajoutez
"$a"
des\"
devis internes et externes ).Essayez ceci (est parfaitement sûr):
A propos du manuel:
Non, il n'y a pas de page de manuel indépendante pour cela. La recherche de manuel avec
man -f eval
ou mêmeapropos eval
ne montre aucune entrée.Il est inclus à l'intérieur
man bash
. Comme est intégré.Recherchez "SHELL BUILTIN COMMANDS" puis "eval".
Un moyen plus simple d’obtenir de l’aide est le suivant: Dans bash, vous pouvez
help eval
voir l’aide de la fonction intégrée.Pourquoi eval est-il appelé le mal?
Parce qu'il s'agit d'un texte contraignant à coder de manière dynamique.
En d'autres termes: il convertit la liste de ses arguments (et / ou développements de tels arguments) en une ligne exécutée. Si, pour une raison quelconque, un argument a été défini par un attaquant, vous allez exécuter du code d’attaquant.
Ou encore plus simplement, avec eval, vous indiquez à quiconque a défini la valeur d'un ou plusieurs arguments:
Est-ce dangereux? Cela devrait être clair pour tout le monde.
La règle de sécurité pour eval devrait être:
N'exécutez eval que sur les variables auxquelles vous avez attribué sa valeur.
Lire plus de détails ici .
la source
eval
est une caractéristique des langues les plus interprétées (TCL
,python
,ruby
...), non seulement des coquilles. Il est utilisé pour évaluer le code de manière dynamique.Dans les shells, il est implémenté en tant que commande intégrée au shell.
Fondamentalement,
eval
prend une chaîne en tant qu'argument et évalue / interprète le code qu'il contient. Dans les shells,eval
peut prendre plus d'un argument, mais ileval
suffit de les concaténer pour former la chaîne à évaluer.C'est très puissant car vous pouvez construire du code de manière dynamique et l'exécuter, chose que vous ne pouvez pas faire dans des langages compilés comme C.
Comme:
Mais c’est aussi dangereux, car il est important de nettoyer les parties dynamiques (fournies de l’extérieur) de ce qui est transféré
eval
car elles sont interprétées comme du code shell.Par exemple, ci-dessus, si
$1
estevil-command; var
,eval
finirait par évaluer leevil-command; var=$varvalue
code shell et ensuite l'exécuterevil-command
.La perversité de
eval
est souvent exagérée.OK, c'est dangereux, mais au moins on sait que c'est dangereux.
Beaucoup d'autres commandes évaluera le code shell dans ses arguments , sinon aseptisé, comme ( en fonction de la coquille),
[
aliastest
,export
,printf
, GNUsed
,awk
et bien sûrsh
/bash
/perl
et tous les interprètes ...Des exemples (ici en utilisant
uname
commeevil-command
et$a
en externe fourni des données hygiénisées):Ces commandes
sed
,export
... pourraient être considérées comme plus dangereuses car, même si c'est évidenteval "$var"
, le contenu de$var
sera évalué en tant que code shell, ce n'est pas si évident avecsed "s/foo/$var/"
ouexport "$var=value"
ou[ "$var" -gt 0 ]
. La dangerosité est la même, mais elle est dissimulée dans ces autres commandes.la source
sed
comme sieval
on passait une chaîne contenue dans une variable, et pour les deux, le contenu de cette chaîne finit par être évalué en tant que code shell, doncsed
c'est aussi dangereux queeval
, c'est ce que je dis.sed
est en train de passer une chaîne contenantuname
(uname n’a pas encore été exécuté) et par l’appel desed
, la commande uname est exécutée. J'aime pour eval. En faitsed 's/foo/$a/g'
, vous ne transmettez pas de données non normalisées àsed
, ce n'est pas ce dont nous parlons ici.Cet exemple peut éclairer un peu:
Sortie du script ci-dessus:
la source
eval
. Pensez-vous que certains aspects fondamentaux et critiques de la fonctionnalitéeval
ne sont pas abordés dans les réponses existantes? Si oui, expliquez -le et utilisez l'exemple pour illustrer votre explication. S'il vous plaît ne répondez pas dans les commentaires; éditez votre réponse pour la rendre plus claire et plus complète.