Respuestas:
$(command)
es "sustitución de comando". Como parece entender, ejecuta command
, captura su salida e inserta eso en la línea de comando que contiene el $(…)
; p.ej,
$ ls -ld $(date +%B).txt
-rwxr-xr-x 1 Noob Noob 867 Jul 2 11:09 July.txt
${parameter}
es "sustitución de parámetros". Se puede encontrar mucha información en la página de manual del shell, bash (1) , bajo el encabezado " Expansión de parámetros ":
${parameter}
El valor del parámetro se sustituye. Las llaves se requieren cuando el parámetro es un parámetro posicional con más de un dígito, o cuando el parámetro va seguido de un carácter que no debe interpretarse como parte de su nombre.
Para los parámetros posicionales, consulte " Parámetros posicionales ", a continuación. En su uso más común, como se muestra en las otras respuestas,
parameter
es un nombre de variable. El ${…}
formulario, como se indica al final del párrafo anterior, le permite obtener el valor de una variable (es decir, ) y seguirlo inmediatamente con una letra, dígito o guión bajo:$variable_name
$ animal = gato $ echo $ animales # No hay variables como "animales". $ echo $ {animal} s gatos $ echo $ animal_food # No existe una variable como "animal_food". $ echo $ {animal} _food comida de gato
También puedes hacer esto con citas:
$ echo "$ animal" s gatos
O, como ejercicio de opciones, podría usar una segunda variable:
$ plural = s $ echo $ animal $ plural gatos
Pero esto es solo el paso 1. El siguiente párrafo en la página del manual es interesante, aunque un poco críptico:
Si el primer carácter del parámetro
es un signo de exclamación ( !
), se introduce un nivel de indirección variable. Bash usa el valor de la variable formada a partir del resto del parámetro
como el nombre de la variable; esta variable se expande y ese valor se usa en el resto de la sustitución, en lugar del valor del parámetro en sí. Esto se conoce como expansión indirecta .
... (excepciones) ...
El signo de exclamación debe seguir inmediatamente a la llave izquierda para introducir la indirección.
No estoy seguro de cómo puedo aclarar esto, excepto por ejemplo:
$ animal = gato $ echo $ animal gato $ cat = tabby $ echo $ cat atigrado $ echo $ {! animal} tabby # Si $ animal es "gato" , entonces $ {! animal} es $ gato , es decir, "tabby"
Entonces llamemos a ese paso 1½. Hay muchas cosas interesantes que puedes hacer como paso 2:
$ animal = gato $ echo $ {# animal} 3 # longitud de cadena $ echo $ {animal / at / ow} vaca # Sustitución
No puedes hacer ninguna de esas cosas sin los {
... }
aparatos ortopédicos.
Parámetros Posicionales
Considere este ejemplo artificial :
$ gato myecho.sh echo $ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 $ 11 $ 12 $ 13 $ 14 $ 15 $ ./myecho.sh Hey diddle diddle, El gato y el violín, La vaca saltó sobre la luna. Hey diddle diddle, El gato y el violín, The Hey0 Hey1 Hey2 Hey3 Hey4 Hey5
debido a que la cáscara no entiende $10
, $11
etc. Se trata $10
como si fuera ${1}0
. Pero sí comprende ${10}
, ${11}
etc., como se menciona en la página del manual ("un parámetro posicional con más de un dígito").
Pero en realidad no escriba guiones como ese; Hay mejores maneras de lidiar con largas listas de argumentos.
Lo anterior (junto con muchas más formas de construcciones) se discuten con mayor detalle en la página de manual del shell, bash (1) .${parameter…something_else}
Una nota sobre cotizaciones
Tenga en cuenta que siempre debe citar las variables de shell a menos que tenga una buena razón para no hacerlo y esté seguro de saber lo que está haciendo. Por el contrario, aunque las llaves pueden ser importantes, no son tan importantes como las comillas.
$ filename = "rima infantil.txt" $ ls -ld $ {filename} ls: no se puede acceder a la guardería: no existe tal archivo o directorio ls: no se puede acceder a rhyme.txt: no existe tal archivo o directorio $ ls -ld "$ nombre de archivo" -rwxr-xr-x 1 Noob Noob 5309 2 de julio 11:09 rima infantil.txt
Eso también se aplica a los parámetros posicionales (es decir, argumentos de línea de comandos; por ejemplo, "$1"
) y también a la sustitución de comandos:
$ ls -ld $ (fecha "+% B% Y"). txt ls: no se puede acceder a julio: no existe tal archivo o directorio ls: no se puede acceder a 2015.txt: no existe tal archivo o directorio $ ls -ld "$ (fecha" +% B% Y "). txt" -rwxr-xr-x 1 Noob Noob 687 2 de julio 11:09 de julio de 2015.txt
Ver cotizaciones del golpe sin escape en sustitución de comandos
durante un breve tratado sobre la interacción entre las cotizaciones y $(
... )
.
!
.
${!animal}
realidad se refiere a la variable en $cat
lugar del valor cat". Sí, ese es exactamente el punto. “¿Cómo / at se convierte en una" c "en echo $ {animal / at / ow}?” ¿Huh? / at no se convierte en "c"; "Gato" se convierte en "vaca" cuando "at" se reemplaza por "ow".
En su ejemplo, $ var y $ {var} son idénticos. Sin embargo, las llaves son útiles cuando desea expandir la variable en una cadena:
$ string=foo
$ echo ${string}bar
foobar
$ echo $stringbar
$
Por lo tanto, las llaves proporcionan una forma de sustituir la variable para obtener el nombre de la nueva variable, que se sustituirá.
Por lo general, lo veo más comúnmente en cadenas. Algo como esto no funcionará:
var="a"
echo "$varRAW_STRING"
Pero esto:
var="a"
echo "${var}RAW_STRING"
Como dijiste correctamente, $()
se usa para ejecutar un comando:
dir_contents=$(ls)
También puedes usar backticks, pero me parece el $()
más versátil. Por un lado, los backticks no pueden (fácilmente) anidarse.
date_directory=`ls `date '+%Y-%m-%d'`` # Makes no sense
date_directory=$(ls $(date '+%Y-%m-%d')) # Much better
date_directory=`ls \`date '+%Y-%m-%d'\``
. Pero es terriblemente feo; $(…)
Es mucho más claro y fácil de usar.
`…`
fue la (única) sintaxis para la sustitución de comandos durante años antes de que $(…)
se inventara, por lo que no necesita imaginar nada: la gente lo hizo.
${
variable_name
}