Hay dos formas de capturar la salida de la línea de comando en bash
:
Backticks de shell Bourne heredados
``
:var=`command`
$()
sintaxis (que hasta donde yo sé es específica de Bash, o al menos no es compatible con shells antiguos que no son POSIX como Bourne original)var=$(command)
¿Hay algún beneficio al usar la segunda sintaxis en comparación con los backticks? ¿O son los dos totalmente 100% equivalentes?
$()
es POSIX y es compatible con todos los shells Bourne modernos, por ejemplo, ksh, bash, ash, dash, zsh, busybox, lo que sea. (Uno no tan moderno es Solaris/bin/sh
, pero en Solaris se aseguraría de usar el moderno en su/usr/xpg4/bin/sh
lugar).$()
y los backticks en los alias. Si tienealias foo=$(command)
en su,.bashrc
entoncescommand
se ejecutará cuando se ejecute el comando alias durante la.bashrc
interpretación. Conalias foo=`command`
,command
se ejecutará cada vez que se ejecute el alias. Pero si escapa$
con el$()
formulario (por ejemploalias foo=\$(command)
), también se ejecutará cada vez que se ejecute el alias, en lugar de durante la.bashrc
interpretación. Por lo que puedo decir por prueba, de todos modos; No puedo encontrar nada en los documentos de bash que explique este comportamiento.`command`
command
se ejecuta solo una vez. Lo comprobé: function aaa () {printf date; echo aaa >> ~ / test.txt; } alias test1 =aaa
. La función aaa se ejecuta solo una vez (después de cada inicio de sesión) sin importar cuántas vecestest1
se haya ejecutado alias ( ). Usé .bashrc (en Debian 10).Respuestas:
La principal es la capacidad de anidarlos , comandos dentro de los comandos, sin perder la cordura tratando de descubrir si alguna forma de escapar funcionará en los backticks.
Un ejemplo, aunque algo artificial:
que le dará una lista de todos los archivos en el
/dir
árbol de directorios que tienen el mismo nombre que el archivo de texto con fecha más temprana de diciembre de 2011 (a) .Otro ejemplo sería algo así como obtener el nombre (no la ruta completa) del directorio principal:
(a) Ahora que el comando específico puede no funcionar realmente, no he probado la funcionalidad. Por lo tanto, si me rechaza, ha perdido de vista la intención :-) Se entiende solo como una ilustración de cómo puede anidar, no como un fragmento listo para la producción libre de errores.
fuente
Do whatever the heck you want with it.
" :-) En cualquier caso, estoy bastante seguro de que fue humor de DVK.Suponga que desea encontrar el directorio lib correspondiente al lugar donde
gcc
está instalado. Tienes una opción:El primero es más fácil que el segundo: use el primero.
fuente
x=$(f); x=`f`
comportarse igual quex="$(f)"; x="`f`"
. Por el contrario, la asignación de matricesx=($(f)); x=(`f`)
hacer realizar a dividir en$IFS
caracteres como se esperaba cuando se invoca comandos. Esto es conveniente (x=1 2 3 4
no tiene sentido) pero inconsistente.x=$(f)
trabajo sin comillas. Debería haber sido más específico; Estaba proponiendo usarlibdir=$(dirname "$(dirname "$(which gcc)")")/lib
(citas alrededor de las sustituciones de comandos internos ). Si no se cita, aún está sujeto a la división habitual de palabras y la expansión global.El backticks (
`...`
) es la sintaxis heredada requerida solo por las capas de bourne más antiguas no compatibles con POSIX y$(...)
es POSIX y más preferido por varias razones:Las barras invertidas (
\
) dentro de los backticks se manejan de una manera no obvia:Las citas anidadas en el interior
$()
son mucho más convenientes:en vez de:
o escribiendo algo como:
porque
$()
usa un contexto completamente nuevo para citarque no es portátil ya que los shells Bourne y Korn requerirían estas barras invertidas, mientras que Bash y dash no.
La sintaxis para las sustituciones de comandos de anidación es más fácil:
que:
porque
$()
impone un contexto completamente nuevo para las citas, por lo que cada sustitución de comandos está protegida y puede tratarse por sí sola sin especial preocupación por las citas y las escapadas. Al usar backticks, se vuelve más y más feo después de dos niveles o más.Pocos ejemplos más:
Resuelve un problema de comportamiento inconsistente cuando se utilizan comillas inversas:
echo '\$x'
salidas\$x
echo `echo '\$x'`
salidas$x
echo $(echo '\$x')
salidas\$x
La sintaxis de Backticks tiene restricciones históricas sobre el contenido del comando incrustado y no puede manejar algunos scripts válidos que incluyen comillas inversas, mientras que el
$()
formulario más nuevo puede procesar cualquier tipo de script incrustado válido.Por ejemplo, estos scripts incrustados válidos no funcionan en la columna izquierda, pero sí funcionan en el IEEE derecho :
Por lo tanto, la sintaxis para la
$
sustitución de comandos prefijada debería ser el método preferido, ya que es visualmente clara con una sintaxis limpia (mejora la legibilidad humana y mecánica), es anidable e intuitiva, su análisis interno es independiente y también es más consistente (con todas las otras expansiones que se analizan entre comillas dobles) donde los backticks son la única excepción y el`
carácter se camufla fácilmente cuando está adyacente para"
hacerlo aún más difícil de leer, especialmente con fuentes pequeñas o inusuales.Fuente: ¿Por qué se
$(...)
prefiere sobre`...`
(backticks)? en BashFAQVer también:
fuente
De man bash:
fuente
Además de las otras respuestas,
destaca visualmente mejor que
Los backticks se parecen demasiado a los apóstrofes; esto varía según la fuente que esté utilizando.
(Y, como acabo de notar, los backticks son mucho más difíciles de ingresar en ejemplos de código en línea).
fuente
$
(
y)
para el backtick; YMMV.$()
permite anidar.Creo que los backticks no lo permiten.
fuente
out=`echo today is \`date\``
.Es el estándar POSIX que define la
$(command)
forma de sustitución de comandos. La mayoría de los shells en uso hoy en día cumplen con POSIX y admiten esta forma preferida sobre la notación arcaica de backtick. La sección de sustitución de comandos (2.6.3) del documento Shell Language describe esto:fuente
Esta es una pregunta heredada, pero se me ocurrió un ejemplo perfectamente válido de
$(...)
más`...`
.Estaba usando un escritorio remoto para Windows ejecutando cygwin y quería iterar sobre el resultado de un comando. Lamentablemente, el carácter de backtick fue imposible de ingresar, ya sea por el escritorio remoto o por el propio cygwin.
Es sensato suponer que un signo de dólar y paréntesis serán más fáciles de escribir en configuraciones tan extrañas.
fuente