web-dev-qa-db-fra.com

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

Pour stocker le résultat d’une commande sous forme de variable dans sh/ksh/bash, vous pouvez effectuer l’une des opérations suivantes:

var=$(command)

ou

var=`command`

Quelle est la différence, le cas échéant, entre les deux méthodes?

238
hhafez

Les backticks/Gravemarks ont été déconseillés en faveur de $() pour la substitution de commande car $() peut facilement s'emboîter en lui-même comme dans $(echo foo$(echo bar)). Il existe d'autres différences, telles que la façon dont les barres obliques inversées sont analysées dans la version backtick/gravemark, etc.

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

Voir également la spécification [~ # ~] [~ # ~] pour des informations détaillées sur les diverses différences.

254
SiegeX

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))

vs.

listing=`ls -l \`cat filenames.txt\``
38
John Kugelman

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

La forme backcoted est la méthode traditionnelle de substitution de commande et est supportée par POSIX.
Cependant, toutes les utilisations, à l'exception des plus simples, se compliquent rapidement.
En particulier, les substitutions de commandes incorporées et/ou l’utilisation de guillemets doubles nécessitent une échappement prudent avec le caractère barre oblique inversée
.

C'est pourquoi git/Documentation/CodingGuidelines mentionne:

Nous préférons $( ... ) pour la substitution de commande; Contrairement à ``, il niche correctement .
Cela aurait dû être comme Bourne l’épelait depuis le premier jour, mais malheureusement pas.

thitoncommenté :

C'est pourquoi `echo `foo`` Ne fonctionnera pas en général à cause de l'ambiguïté inhérente au fait que chaque `` Peut être ouvert ou fermé.
Cela pourrait fonctionner dans des cas particuliers en raison de la chance ou de caractéristiques spéciales.


Mise à jour de janvier 2016: Git 2.8 (mars 2016) supprime totalement les backticks.

Voir commit ec1b76 , commit 9c10377 , commit c7b793a , commit 80a6b3f , commit 9375dcf , commit e74ef6 , commit 27fe43e , commit 2525c51 , commit becd67f , commit a5c98ac , commit 8c311f9 , commit 57da049 , commit 1d9e86f , commit 78ba28d , commit efa639f , commit 1be2fa , commit 38e9476 , commit 8823d2f , commit 32858a , commit cd914d8 (12 janv. 2016) par Elia Pinto (devzero2000)) .
(Fusionnée par Junio ​​C Hamano - gitster - dans commit e572fef , 22 janvier 2016)

Depuis Git 2.8, tout est $(...), pas plus `...`.

25
VonC

Lorsque la forme de back-tick la plus ancienne est utilisée, la barre oblique inversée conserve sa signification littérale, sauf lorsqu'elle est suivie de $, `ou \. Le premier retour arrière non précédé d'une barre oblique inverse met fin à la substitution de commande.

Lors de l'utilisation de la nouvelle forme $(command), tous les caractères entre les parenthèses constituent la commande; aucun n'est traité spécialement.

Les deux formes peuvent être imbriquées, mais la variété avec back-tick nécessite la forme suivante.

`echo \`foo\`` 

Par opposition à:

$(echo $(foo))
25
ocodo

Il y a peu de différence, sauf pour les caractères non échappés que vous pouvez utiliser dans la commande. Vous pouvez même mettre les commandes `...` à l'intérieur de $ (...) celles-ci (et vice versa) pour une substitution de commande plus complexe à deux niveaux.

Il existe une interprétation légèrement différente du caractère/opérateur de la barre oblique inverse. Entre autres choses, lors de l’imbrication des commandes `...`, vous devez échapper aux caractères ` internes avec \, alors que $ () sous-poste comprend automatiquement l'imbrication.

5
DigitalRoss

"Quelle est la différence, le cas échéant, entre les deux méthodes?"

Faites attention à ce comportement:

A="A_VARIABLE"
echo "$(echo "\$A")"
echo "`echo "\$A"`"

Vous obtiendrez ces résultats:

$A
A_VARIABLE

0
Hiro