Entre les alternatives suivantes ...
avec
eval
.comd="ls" eval "$comd"
avec
source /dev/stdin
printf "ls" | source /dev/stdin
avec
source /dev/stdin
et( )
ou{ }
( printf "ls" ) | source /dev/stdin { printf "ls"; } | source /dev/stdin
(Quand nous courons
printf
à{ }
, est - il un avantage autre que ne pas utiliser sous - shell?)Quelle est la différence entre eux?
Quel est préféré?
Quelle est la meilleure façon d'exécuter des commandes?
()
ou{}
?
bash
command-line
MS.Kim
la source
la source
Réponses:
de
bash manpage
:Il n'y a aucune différence entre les deux façons.
Il n'y a qu'une seule note:
eval
concaténé tous ses arguments, qui est ensuite exécuté comme une seule commande.source
lit le contenu d'un fichier et l'exécute.eval
ne peut construire des commandes qu'à partir de ses arguments, nonstdin
. Vous ne pouvez donc pas faire comme ça:Votre exemple fournit le même résultat, mais le but de
eval
etsource
est différent.source
est généralement utilisé pour fournir une bibliothèque pour d'autres scripts, tandis queeval
n'est utilisé que pour évaluer les commandes. Vous devez éviter d'utilisereval
si possible, car il n'y a aucune garantie que la chaîne évaluée est propre; nous devons faire quelques vérifications de santé mentale, en utilisant à lasubshell
place.Lorsque vous exécutez des commandes de séquences à l'intérieur d'une accolade
{ }
, toutes les commandes sont exécutées dans le shell actuel , au lieu d'une sous- coque (ce qui est le cas si vous exécutez entre parenthèses (voir référence bash )).L'utilisation
subshell ( )
utilise plus de ressources, mais votre environnement actuel n'est pas affecté. L'utilisation{ }
exécute toutes les commandes du shell actuel, de sorte que votre environnement est affecté. Selon votre objectif, vous pouvez en choisir un.la source
eval
parsource
. Je suppose que la question est: esteval "$cmd"
équivalent àecho "$cmd" | source /dev/stdin
. Mon opinion actuelle est: oui.La principale différence est que les 2e et 3e formes utilisent un tube, ce qui forcera bash à exécuter la commande "source" dans un sous-shell (à moins que lastpipe ne soit défini, uniquement disponible dans bash 4.2+), ce qui le rendra à peu près équivalent à :
Les conséquences sont que toutes les variables d'environnement définies par votre code seront perdues, donc cela ne fonctionnera pas comme prévu:
Pour exécuter les commandes dans le shell actuel, vous pouvez utiliser la substitution de processus:
Vous pouvez mettre plus de commandes entre parenthèses en utilisant le point-virgule comme d'habitude.
Si vous éliminez le tuyau de cette façon, je pense qu'il n'y a pas de différence entre utiliser "eval" et "source". Vous devriez préférer celui qui est le plus simple à utiliser dans votre cas particulier:
la source
En complément des réponses déjà données:
Un
source
équivalent à ...... est ...
En cas de
ls
il n'y a pas de différence significative.Mais dans le cas d'une commande qui est destinée à affecter votre environnement actuel (ce que vous avez généralement l'intention d'utiliser
source
), cette variante le ferait (comme leeval
ferait également votre 1ère solution ) tandis que votre 2ème approche affecte simplement l'environnement d'un sous-shell qui a gagné '' t être disponible après avoir exécuté votre ligne de code.la source