Eval $ (cat filename) est-il le même que le fichier source?

9

Travaillant sur certaines fonctions bash, je ne connaissais pas la source ...commande, j'ai donc utilisé à la eval $(cat ...)place. Maintenant, je me demande si je devrais changer chaque utilisation ou est-ce juste la même fonction?

Ils semblent fonctionner de la même façon maintenant, mais il y aura peut-être des différences trompeuses plus tard, je veux juste savoir.

Benjamin
la source

Réponses:

6

eval $(cat ...)ne fonctionne pas dans tous les cas. Par exemple, les sauts de ligne sont convertis en un seul espace $(cat ...)avant le traitement du contenu eval. Cela rompt souvent les instructions sur plusieurs lignes comme les boucles et ici les documents.

Essayez par exemple le fichier suivant avec les deux méthodes:

for i in 1 2 3; do
 echo $i
done

cat<<EOF
a
b
c
EOF
Florian Diesch
la source
4
Si vous utilisez des guillemets, l'espace blanc restera intact:eval "$(cat file)"
glenn jackman
1
Oui, cela devrait aussi fonctionner. Mais si l'on doit changer le code de toute façon, je préfère sourcecar c'est une commande spécialement conçue pour cela.
Florian Diesch
9

Comme déjà mentionné par @glennjackman, vous voudrez citer la substitution de commande, sinon le fractionnement de mots et l'expansion du nom de chemin modifieront le contenu avant qu'il ne soit évalué. Et bien que les deux exécutent les commandes à partir du fichier, il existe des différences.

  • Lorsque vous source d' un script, diverses variables shell spéciaux seront modifiés, principalement BASH_SOURCE, BASH_LINENOet des FUNCNAMEtableaux. Ils sont utiles pour imprimer des messages d'erreur et déboguer.

  • Vous pouvez revenir d'un script d'origine avec la returncommande ( help return). Avec l'eval, vous n'obtiendrez pas cet effet. De même, un piège RETOUR ne sera pas déclenché pour l'évaluation.

  • Lorsque vous sourcez un script, vous pouvez lui passer des arguments. Vous ne pouvez pas faire ça avec cet eval.

  • Avec l'eval, la substitution de commande lira tout le contenu du fichier en mémoire avant de le transmettre à eval. Lorsque vous le sourcez, bash lira le fichier au fur et à mesure.

geirha
la source
1

Il y a un bon résumé de ce que font source, eval et exec ici: http://www.unix.com/shell-programming-scripting/54347-bash-shell-exec-eval-source-looking-help-understand.html

Je pense que votre utilisation de eval et de la source du fichier fera la même chose. Je ne suis pas complètement sûr, cependant, que les variables à l'intérieur de l'indice se comporteront de la même façon dans tous les cas. Je recommanderais d'utiliser la source si possible, car c'est la façon la plus simple d'aller et rend votre code plus lisible.

Hinz
la source
3
complètement tangentiel: bash a un raccourci pour $(cat file)->$(< file)
glenn jackman