web-dev-qa-db-fra.com

Comprendre le backtick (`)

J'essaye la commande

$ b=5; echo `$b`;
-bash: 5: command not found

mais il n'imprime pas 5 comme il est censé le faire. Qu'est-ce que j'oublie ici?

Que signifie `(backquote/backtick) dans les commandes? semble dire que ` évalue les commandes à l'intérieur et les remplace par la sortie.

37
coolcric

Le texte entre les backticks est exécuté et remplacé par la sortie de la commande (moins les caractères de retour à la ligne de fin, et prenez garde que les comportements de Shell varient quand il y a des caractères NUL dans la sortie). Cela s'appelle substitution de commande car il est remplacé par la sortie de la commande. Donc, si vous voulez imprimer 5, vous ne pouvez pas utiliser de guillemets, vous pouvez utiliser des guillemets, comme echo "$b" Ou simplement supprimer n'importe quelle citation et utiliser echo $b.

Comme vous pouvez le voir, puisque $b En contient 5, lors de l'utilisation de backticks bash tente d'exécuter la commande 5 Et comme il n'y a pas une telle commande, il échoue avec un message d'erreur.

Pour comprendre le fonctionnement des backticks, essayez d'exécuter ceci:

$ A=`cat /etc/passwd | head -n1`
$ echo "$A"

cat /etc/passwd |head -n1 Devrait imprimer la première ligne du fichier /etc/passwd. Mais puisque nous utilisons des backticks, il ne l'imprime pas sur la console. Au lieu de cela, il est stocké dans la variable A. Vous pouvez faire écho à $A À cela. Notez qu'un moyen plus efficace d'imprimer la première ligne utilise la commande head -n1 /etc/passwd Mais je voulais souligner que l'expression à l'intérieur des backticks ne doit pas être simple.

Donc, si la première ligne de/etc/passwd est root:x:0:0:root:/root:/bin/bash, La première commande sera dynamiquement remplacée par bash par A="root:x:0:0:root:/root:/bin/bash".

Notez que cette syntaxe est celle du Bourne Shell. Citer et s'échapper devient rapidement un cauchemar, surtout lorsque vous commencez à les imbriquer. Ksh a introduit l'alternative $(...) qui est maintenant standardisée ( POSIX ) et supportée par tous les shells ( même le Bourne Shell d'Unix v9). Vous devriez donc utiliser $(...) à la place de nos jours à moins que vous n'ayez besoin d'être portable avec de très vieux shells Bourne.

Notez également que la sortie de `...` Et $(...) est sujette au fractionnement de Word et à la génération de nom de fichier tout comme l'expansion de variable (en zsh, fractionnement de Word uniquement), donc devrait généralement être cité dans la liste contextes.

55
Krzysztof Adamski

Le backtick fait exactement ce que vous dites. Vous avez défini une variable sur un entier. Lorsque vous placez cette variable entre guillemets, bash essaiera de l'exécuter en tant que commande. Puisqu'il ne s'agit pas d'une commande, vous obtenez l'erreur que vous avez vue.

Ce que vous voulez faire, c'est simplement:

$ b=5; echo $b

Pour mieux comprendre les backticks, comparez avec:

$ b=5; a=`echo $b`; echo $a
  5
11
terdon

En allant étape par étape, votre ligne devrait l'expliquer.

$ b=5; echo `$b`;
  1. définit la variable b sur 5
  2. évalue $b (exécute efficacement 5)
  3. echoes la sortie de l'évaluation ci-dessus.

Alors oui, la sortie que vous avez obtenue est attendue. Vous évaluez le contenu d'une variable, pas la commande réelle que vous pensiez être. Tout ce que vous mettez dans les backticks est évalué (exécuté) dans un nouveau (sous-) shell.

8
gertvdijk