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?

Tshepang
la source
18
Voir aussi: BashFAQ / 082 .
Dennis Williamson
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 :)

remuer
la source
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.

balki
la source
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.

mouviciel
la source
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".

cuonglm
la source
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.)

phk
la source
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 \\\`\``
Emmanuel
la source
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