Pourquoi ne fonctionne pas ce code bash?
Question
x="a=b"
`echo $x`
echo $a
Je me attends à la deuxième ligne pour générer « a = b », et l'exécuter dans le contexte de la coque principale, ce qui entraîne une nouvelle a
variable avec une valeur b
.
Cependant, ce que je comprends vraiment (si je saisir les commandes) est le message d'erreur après la deuxième ligne, bash: a=b: command not found
Pourquoi est-ce donc?
La solution
Il est à cause de l'ordre dans lequel bash analyse la ligne de commande. Il semble pour la définition des variables (par exemple a=b
) avant effectuer la substitution de variable et de commande (par exemple des commandes dans backticks). À cause de cela, par le echo $x
temps est remplacé par a=b
, il est trop tard pour bash voir cela comme une définition variable et il est analysé comme une commande à la place. La même chose se serait passé si vous venez d'utiliser $x
comme la commande (au lieu d'écho dans les apostrophes inverses). Comme dans la réponse de @ MVDS, la commande eval
peut être utilisé pour forcer la commande à être parsé à nouveau depuis le début, ce qui signifie que ce sera reconnu comme une définition de variable:
$ x="a=b"
$ `echo $x`
-bash: a=b: command not found
$ $(echo $x) # Exact same thing, but with cleaner syntax
-bash: a=b: command not found
$ $x # This also does the same thing, but without some extra steps
-bash: a=b: command not found
$ eval "$x" # This will actually work
$ echo $a
b
$ a= # Start over
$ eval "$(echo "$x")" # Another way of doing the same thing, with extra steps
$ echo $a
b
Notez que lors de l'utilisation eval
j'ai mis toutes les références à $x
guillemets doubles - est d'éviter les phases ultérieures de l'analyse syntaxique bash (par exemple, la séparation de mots) de se produire deux fois , depuis bash terminer son processus d'analyse syntaxique régulière, puis reconnaître la commande eval
, puis refaire l'ensemble du processus d'analyse syntaxique nouveau . Il est vraiment facile d'obtenir des résultats inattendus d'utiliser eval
, et cela supprime au moins une partie du potentiel des ennuis.
Autres conseils
Essayez
eval $x
(Et nous avons besoin de 30 caractères pour cette réponse à être affiché)
Qu'est-ce que votre première ligne d'écho n'est en cours d'exécution dans un sous-shell et retourne sa valeur à la .. Le même appelé résultat est obtenu à l'aide $()
et est - par la voie -. Facile à utiliser que les apostrophes inverses
Alors, ce que vous faites est d'abord echo $x
en cours d'exécution (qui retourne a=b
). Et, en raison des accents graves, a=b
est retourné à la coquille qui tente d'exécuter cette ligne comme une commande qui - évidemment -. Ne fonctionnera pas
Essayez ceci dans un shell:
$(echo ls)
Et vous verrez clairement ce qui se passe.
Avez-vous essayé $x
en ce que apostrophes drôle? Sans echo
, l'écho semble être que pour afficher la chaîne, pas exécuter des commandes.