Quelle est la différence entre $ (commande) et `command` dans la programmation du shell?

Pour stocker la sortie d’une commande en tant que variable dans sh / ksh / bash, vous pouvez soit faire

var=$(command) 

ou

 var=`command` 

Quelle différence y a-t-il entre les deux méthodes?

Les backticks / gravemarks ont été désapprouvés au profit de $() pour la substitution de commandes, car $() peut facilement s’immerger comme dans $(echo foo$(echo bar)) . Il existe d’autres différences, telles que la manière dont les barres obliques inverses sont analysées dans la version backtick / gravemark, etc.

Voir BashFAQ / 082 pour plusieurs raisons pour toujours préférer la syntaxe $ (…).

Voir également la spécification POSIX pour des informations détaillées sur les différentes différences.

Ils se comportent de la même manière. La différence est syntaxique: il est plus facile d’imbriquer $() que `` :

 listing=$(ls -l $(cat filenames.txt)) 

contre.

 listing=`ls -l \`cat filenames.txt\`` 

Lorsque l’ancienne forme de coche arrière est utilisée, la barre oblique inverse conserve sa signification littérale, sauf lorsqu’elle est suivie de $, `ou \. Le premier retour en arrière non précédé d’une barre oblique inverse termine la substitution de commande.

Lorsque vous utilisez le nouveau formulaire $(command) , tous les caractères entre parenthèses constituent la commande; aucun n’est traité spécialement.

Les deux formes peuvent être nestedes, mais la forme de coche arrière nécessite la forme suivante.

 `echo \`foo\`` 

Par opposition à:

 $(echo $(foo)) 

Juillet 2014: Le commit f25f5e6 (par Elia Pinto ( devzero2000 ) , avril 2014, Git 2.0) ajoute au problème de l’imbrication:

La forme cotée est la méthode traditionnelle de substitution de commandes, prise en charge par POSIX.
Cependant, toutes les utilisations sauf les plus simples se compliquent rapidement.
En particulier, les substitutions de commandes intégrées et / ou l’utilisation de guillemets doubles nécessitent une évasion prudente avec le caractère barre oblique inverse .

C’est pourquoi le git / Documentation / CodingGuidelines mentionne:

Nous préférons $( ... ) pour la substitution de commandes; contrairement à “, il niche correctement .
Bourne aurait dû le faire dès le premier jour, mais ce n’est malheureusement pas le cas.

thiton a commenté :

C’est pourquoi `echo `foo`` ne fonctionnera pas en général à cause de l’ambiguïté inhérente car `` peut être ouvert ou fermé.
Cela peut fonctionner pour des cas particuliers en raison de la chance ou de caractéristiques spéciales.


Mise à jour Janvier 2016: Git 2.8 (mars 2016) se débarrasse complètement des backticks.

Voir commettre ec1b763 , commettre 9c10377 , commettre c7b793a , commettre 80a6b3f , commettre 9375dcf , commettre e74ef60 , commettre 27fe43e , commettre 2525c51 , commettre becd67f , commettre a5c98ac , commettre 8c311f9 , commettre 57da049 , commettre 1d9e86f , commettre 78ba28d , commettre efa639f , commettre 38e9476 , commettre 8823d2f , commettre 32858a0 , commettre cd914d8 (12 janvier 2016) par Elia Pinto ( devzero2000 ) .
(Fusion par Junio ​​C Hamano – gitster – dans commit e572fef , 22 janvier 2016)

A partir de Git 2.8, c’est tout $(...) , pas plus `...` .

Il y a peu de différence, sauf pour ce qui est des caractères non échappés que vous pouvez utiliser dans la commande. Vous pouvez même placer des commandes `…` dans $ (…) (et vice versa) pour une substitution de commande à deux niveaux plus compliquée.

Il y a une interprétation légèrement différente du caractère / opérateur de barre oblique inverse. Entre autres choses, lors de l’imbrication de commandes de substitution, vous devez échapper les caractères internes avec \, alors qu’avec $ (), la sous- configuration comprend automatiquement l’imbrication.