¿Cuál es la diferencia entre $ (comando) y `comando` en la progtwigción de shell?

Para almacenar la salida de un comando como una variable en sh / ksh / bash, puede hacer cualquiera

var=$(command) 

o

 var=`command` 

¿Cuál es la diferencia si alguno entre los dos métodos?

Los backticks / gravemarks han quedado en desuso en favor de $() para la sustitución de comandos porque $() puede anidar fácilmente dentro de sí mismo como en $(echo foo$(echo bar)) . Existen otras diferencias, como la forma en que se analizan las barras invertidas en la versión backtick / gravemark, etc.

Consulte BashFAQ / 082 por varias razones para preferir siempre la syntax $ (…).

También vea la especificación POSIX para obtener información detallada sobre las diversas diferencias.

Ellos se comportan igual. La diferencia es sintáctica: es más fácil anidar $() que `` :

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

vs.

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

Cuando se usa la forma más antigua de retroceso, la barra invertida conserva su significado literal, excepto cuando está seguido de $, `, o \. La primera marca de retroceso no precedida de una barra invertida termina la sustitución del comando.

Al usar el formulario $(command) , todos los caracteres entre paréntesis componen el comando; ninguno es tratado especialmente.

Ambas formas se pueden anidar, pero la variedad de la marca de retroceso requiere la siguiente forma.

 `echo \`foo\`` 

Opuesto a:

 $(echo $(foo)) 

Julio de 2014: la confirmación f25f5e6 (por Elia Pinto ( devzero2000 ) , abril de 2014, Git 2.0) se sum al problema de anidación:

La forma backquoted es el método tradicional para la sustitución de comandos, y es compatible con POSIX.
Sin embargo, todos los usos menos simples se vuelven complicados rápidamente.
En particular, las sustituciones de comando incrustadas y / o el uso de comillas dobles requieren un escape cuidadoso con el carácter de barra inclinada invertida .

Es por eso que el git / Documentation / CodingGuidelines menciona:

Preferimos $( ... ) para sustitución de comando; a diferencia de “, anida correctamente .
Debería haber sido la forma en que Bourne lo deletreó desde el primer día, pero desafortunadamente no lo es.

thiton comentó :

Es por eso que `echo `foo`` no funcionará en general debido a la ambigüedad inherente porque cada `` se puede abrir o cerrar.
Podría funcionar en casos especiales debido a la suerte o características especiales.


Actualización de enero de 2016: Git 2.8 (marzo de 2016) se deshace por completo de los apoyos.

Consulte commit ec1b763 , commit 9c10377 , commit c7b793a , commit 80a6b3f , commit 9375dcf , commit e74ef60 , commit 27fe43e , commit 2525c51 , commit becd67f , commit a5c98ac , commit 8c311f9 , commit 57da049 , commit 1d9e86f , commit 78ba28d , commit efa639f , commit 1be2fa0 , commit 38e9476 , commit 8823d2f , commit 32858a0 , commit cd914d8 (12 Jan 2016) por Elia Pinto ( devzero2000 ) .
(Fusionada por Junio ​​C Hamano – gitster – in commit e572fef , 22 de enero de 2016)

Desde Git 2.8 en adelante, es todo $(...) , no más `...` .

Hay poca diferencia, excepto por los caracteres no escamados que puede usar dentro del comando. Incluso puede poner “ ` comandos dentro de $ (…) unos (y viceversa) para una sustitución de comando de dos niveles más complicada.

Hay una interpretación ligeramente diferente del carácter / operador de barra inclinada invertida. Entre otras cosas, al anidar comandos de sustitución `…` , debe escapar de los ` caracteres internos con \, mientras que con la substición $ () entiende el anidamiento automáticamente.

“¿Cuál es la diferencia si alguno entre los dos métodos?”

Presta atención a este comportamiento:

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

Obtendrás estos resultados:

 $A A_VARIABLE