Quelle est la différence entre $ (stuff) et `stuff`?


265

Il existe deux syntaxes pour la substitution de commande: avec dollar-parentheses et avec backticks. Courir top -p $(pidof init)et top -p `pidof init`donne le même résultat. S'agit-il de deux manières de faire la même chose ou existe-t-il des différences?


18

43
Pendant une seconde, j’ai pensé que c’était une question jQuery.
David Murdoch

Le résultat peut dépendre du shell - certains supportent les deux.
artdanil

Réponses:


360

Les citations arrières de style ancien ` `traitent les barres obliques inverses et les imbrications un peu différentes. Le nouveau style $()interprète tout ce qui se trouve entre les deux ( )comme une commande.

echo $(uname | $(echo cat))
Linux

echo `uname | `echo cat``
bash: command substitution: line 2: syntax error: unexpected end of file
echo cat

fonctionne si les cotes arrière imbriquées sont échappées:

echo `uname | \`echo cat\``
Linux

fun backslash:

echo $(echo '\\')
\\

echo `echo '\\'`
\

Le nouveau style $()s'applique à tous les shells conformes à POSIX .
Comme le soulignait le mouviciel , l’ancien style ` `pourrait s’avérer nécessaire pour les coquillages plus anciens.

Outre le point de vue technique, le style ancien ` `présente également un inconvénient visuel:

  • Difficile à remarquer: I like $(program) better than `program`
  • Facilement confondu avec un seul devis: '`'`''`''`'`''`'
  • Pas si facile à taper (peut-être même pas sur la disposition standard du clavier)

(et SE utilise ` `à ses propres fins, c’était pénible d’écrire cette réponse :)


10
La seule chose que je voudrais ajouter, c'est que j'appelle '(' une paren, pas une parenthèse (qui est '[').
Kendall Helmstetter Gelner le

@Kendall: et ici je pensais que '{' était la tranche gauche pour toutes ces années ...
SamB

5
@ Sam: { }est généralement appelée « accolades » ou « accolades » en.wikipedia.org/wiki/Braces_(punctuation)#Braces
Jørn Schou-Rode

2
Je me réfère également à «{» comme des accolades. Bien que cela semble étrange, vous devez ajouter le qualificatif "bouclé" si vous appelez les autres éléments entre crochets ... Je suppose que c'est simplement parce qu'ils se recourbent.
Kendall Helmstetter Gelner le

1
@slim Je ne sais pas sur les claviers US / UK, mais sur les claviers espagnols `est une touche morte, je dois donc taper soit un double backtick (quelque chose que j'oublie généralement que je peux même faire) ou backtick puis de l'espace, qui est un douleur.
Darkhogg

41

La différence évidente que j’observe est que vous ne pouvez pas imbriquer des backticks tant que vous le pouvez $(). Peut-être que les deux existent pour des raisons d'héritage. De même, les commandes .et sourcesont des synonymes.


10
Certains coquillages dérivés de Bourne ne reconnaissent pas source. Dash est un exemple.
Dennis Williamson

14
Ce n'est pas vrai. Vous pouvez imbriquer des backtick à n'importe quel niveau, mais plus douloureusement. Notez que les deux $(...)et `...`sont standard (le dernier étant déconseillé) alors que .c'est standard mais passource
Stéphane Chazelas

3
Correction, seulement dans (t)cshne peuvent-ils pas être imbriqués. (t)cshne supporte pas $(...)si. Ils soutiennent source(et pas .) cependant.
Stéphane Chazelas

28

$()ne fonctionne pas avec le vieux shell Bourne. Mais cela fait des années que je travaille avec le vieil shell Bourne.


Vieux comme dans les années 1970 et le début des années 1980, correct?
Christopher

6

Une autre note, $()utilisera plus de ressources système que d'utiliser des backticks, mais est légèrement plus rapide.

En maîtrisant les scripts de shell Unix , Randal K. Michael avait effectué un test dans un chapitre intitulé "24 manières de traiter un fichier ligne par ligne".


2
Cette affirmation est un non-sens. Il n'y a aucune raison pour que cela soit plus rapide car il utilise simplement une notation différente pour l'analyseur.
Schily

@schily: Peut-être, je ne cite que du livre, vous pouvez le lire pour plus de détails.
jeudi

3
J'aurais tendance à être d'accord avec @schily ... pourquoi cela prendrait-il plus de ressources?
Wildcard

2
@Wildcard, je suppose que c'est parce $()que votre script est plus grand d'un octet que s'il était utilisé `(en supposant que vous ne les imbriquiez pas et que vous n'utilisiez pas de barres obliques inverses). Quant à savoir ce qui serait le plus rapide à analyser, cela varierait d'une coquille à l'autre et serait sans importance, car négligeable par rapport au coût de la création d'un tuyau et de la mise en œuvre du processus qu'entraîne la substitution.
Stéphane Chazelas

5

Pour ajouter à ce que d'autres ont dit ici, vous pouvez utiliser les backticks pour simuler des commentaires en ligne:

echo foo `# I'm a comment!` bar

La sortie est: foo bar.

Voir les informations suivantes pour plus d'informations: https://stackoverflow.com/a/12797512 (Notez également les commentaires ci-dessous.)


1

La $()syntaxe ne fonctionnera pas avec l’ancien shell Bourne.
Avec des shells plus récents ` `et $()équivalents, il $()est beaucoup plus pratique à utiliser lorsque vous devez imbriquer plusieurs commandes.

Par exemple :

echo $(basename $(dirname $(dirname /var/adm/sw/save )))

est plus facile à taper et à déboguer que:

echo `basename \`dirname \\\`dirname /var/adm/sw/save \\\`\``

1
Bien que $ () puisse paraître agréable, implémenter un analyseur lié pose un problème, car il nécessite un analyseur récursif double.
Schily

6
@schily De l'autre côté, ce qui serait une coquille sans un bon analyseur.
Emmanuel

1
Le problème est que vous devez savoir où se termine la chaîne avant d'appeler l'analyseur. C'est relativement simple avec les backticks, mais c'est difficile avec les crochets car ils sont utilisés à des fins diverses dans la coque. Vous avez donc besoin de l'analyseur deux fois et d'une manière qui n'existe pas dans Bourne Shell.
Schily
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.