¿Qué significa en shell cuando ponemos un comando dentro del signo de dólar y paréntesis: $ (comando)

110

Solo quiero entender la siguiente línea de código en shell. Se utiliza para obtener el directorio de trabajo actual. Soy consciente de que el $(variable)nombre devuelve el valor dentro del nombre de la variable, pero ¿qué se $(command)supone que debe devolver? ¿Devuelve el valor después de ejecutar el comando? En ese caso, podemos usar `para ejecutar el comando.

CWD="$(cd "$(dirname $0)"; pwd)"

La misma salida se puede tomar de la siguiente línea de código también en diferentes versiones de shell

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

No puedo entender el significado de $(cd..y $(dirname.

¿Alguien podría ayudarme a descubrir cómo se ejecuta este comando?

KItis
fuente
1
Y aquí hay una pregunta sobre las ventajas / desventajas de $()vs ``.: stackoverflow.com/questions/9449778/…
Ninguno

Respuestas:

115

El uso de $similares ${HOME}da el valor de HOME. El uso de medios $similares $(echo foo)ejecuta lo que esté dentro del paréntesis en una subcapa y lo devuelve como valor. En mi ejemplo, obtendría fooya echoque escribirá fooen la salida estándar

Eric Urban
fuente
37
Si; $(...)es una mejor forma de escribir un comando que intentar utilizar comillas inversas. Considere la posibilidad de escribir: gcclib=$(dirname $(dirname $(which gcc)))/libutilizando comillas inversas. Incluso antes de tener las dificultades de hacerlo en Markdown, es más difícil porque tiene que escapar de las comillas inversas de los comandos anidados, mientras que no lo hace con la $(...)notación.
Jonathan Leffler
7
Técnicamente, $(echo foo)crea una sustitución de comando, no una subcapa. La otra respuesta actual es correcta. Creo que la sustitución de comandos se ejecuta en una subcapa, más o menos, pero siguen siendo conceptos diferentes.
trysis
4
@trysis: la sustitución de comandos definitivamente se ejecuta en una subcapa , por lo que vale la pena señalarlo.
Eliran Malka
2
Entiendo que las comillas invertidas producen el mismo resultado que $ (), pero ¿la diferencia es puramente cosmética? ¿Hay alguna razón para usar uno frente al otro, aparte de que $ () es más legible?
Mitchell Tracy
2
"El uso de $ like $ (echo foo) significa ejecutar lo que esté dentro del paréntesis en una subcapa y devolverlo como valor". ... Esto es confuso, ya que este comando $(echo foo)intentará ejecutar lo que se devuelve desde el paréntesis, primero se ejecutará y echo fooluego intentará ejecutarse, lo fooque da un error
Contador م
21
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

¿Alguien podría ayudarme a descubrir cómo se ejecuta este comando?

Veamos diferentes partes del comando. BASH_SOURCEes una variable de matriz de bash que contiene nombres de archivo de origen. Entonces "${BASH_SOURCE[0]}"le devolvería el nombre del archivo de script.

dirnamees una utilidad proporcionada por GNU coreutils que elimina el último componente del nombre del archivo. Por lo tanto, si ejecuta su script diciendo bash foo, "$( dirname "${BASH_SOURCE[0]}" )"volvería .. Si lo dijeras bash ../foo, volvería ..; porque bash /some/path/foovolvería/some/path .

Finalmente, todo el comando "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" obtiene el directorio absoluto que contiene el script que se invoca.

$(...) permite la sustitución de comandos, es decir, permite que la salida de un comando reemplace al comando en sí y se puede anidar.

devnull
fuente
1
Perdón por llegar 3 años tarde a la fiesta, pero ¿podrías explicar por qué funciona la declaración? Dijiste que dirnamedevuelve la ruta del archivo ejecutado (relativa o absoluta al directorio de trabajo actual), cdcambia el pwd a ese directorio e pwdimprime la ruta absoluta del directorio de trabajo actual. Pero, ¿por qué se les unen &&? ¿Y qué DIRaguantará si cdfalla?
Christian
2
@Christian, &&evita que se pwdejecute si cdfalla, de modo que DIRestará vacío en lugar de tener un directorio incorrecto.
Charles Duffy