¿Qué es esta variable de forma = $ (...)

9

Qué significa lo siguiente:

basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

Estoy particularmente interesado en esta parte:

varible=$(...)

Sé que los paréntesis se usan para ejecutar un subproceso, pero ¿y si se usan junto con $?

Maxim Koretskyi
fuente
3
Si está utilizando bash: mire la página de manual man bashy busque la sustitución de comandos
FloHe

Respuestas:

16

Del manual de Bash ( man bash):

   Sustitución de comando
       La sustitución de comandos permite que la salida de un comando reemplace el
       nombre del comando Hay dos formas:

              $ (comando)
       o
              `comando`

       Bash realiza la expansión ejecutando el comando en una subshell
       entorno y reemplazando la sustitución de comandos con el estándar
       salida del comando, con cualquier nueva línea final eliminada. Incrustado
       las líneas nuevas no se eliminan, pero pueden eliminarse durante Word
       terrible. La sustitución del comando $ (archivo cat) se puede reemplazar por el
       equivalente pero más rápido $ (<archivo).

(Esto es cierto para todos Bourne-como conchas, es decir sh, ksh, zsh, bashetc., y zshtambién es capaz de capturar datos con caracteres NUL incrustados en esta forma)

El comando

basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

asignará el nombre del directorio donde se encuentra el script (al mismo tiempo que cambia todas las barras diagonales inversas a barras diagonales) a la variable basedir. Los errores, advertencias u otros mensajes de diagnóstico que se envían al flujo de error estándar se seguirán mostrando en el terminal ( $(...)solo captura la salida estándar del comando).

El shell comenzará ejecutando la sustitución de comando más interna:

echo "$0" | sed -e 's,\\,/,g'

La salida de eso se dará como una cadena a dirname, y la salida de eso se asignará a la variable basedir.

Las comillas dobles están ahí para asegurarse de que no se realizará la división de palabras o el bloqueo de nombre de archivo, de lo contrario, puede encontrar que el script falla o produce una salida extraña cuando $0(el nombre del script, incluida la ruta utilizada para ejecutarlo) contiene un espacio carácter o un carácter global de nombre de archivo (como ?o *).

En general, es una buena idea citar siempre expansiones (expansiones variables, sustituciones de comandos y expansiones aritméticas). Vea esta pregunta y sus respuestas para obtener una excelente explicación de por qué es una buena idea.

Si el script se ejecutó como

$ /usr/local/bin/script.sh

entonces basedirobtendrá el valor de /usr/local/bin.

O, en Cygwin:

$ bash c:\\Users\\Me\\script.sh

entonces basedirobtendrá el valor de c:/Users/Me. La doble barra diagonal inversa en la línea de comando en este caso es solo para escapar de la barra diagonal inversa simple del shell. El valor real de $0es c:\Users\Me\script.sh.

Otra forma de hacer lo mismo sin usar dirname, echoy sedsería

basedir="${0//\\//}"
basedir="${basedir%/*}"
Kusalananda
fuente
gracias, así que básicamente comienza a analizar desde el paréntesis más interno, ¿correcto? y por qué se usan las citas?
Maxim Koretskyi
@Maximus Correcto. He actualizado mi respuesta con más información.
Kusalananda
Tal vez deberías decir "es cierto para todos los proyectiles tipo Bourne". Un poco más claro de esa manera
Sergiy Kolodyazhnyy
@Serg, tenga en cuenta que el shell Bourne (como el /bin/shde Solaris 10 o anterior) no era compatible $(...).
Stéphane Chazelas
@ StéphaneChazelas Incorporaré esto.
Kusalananda
6

Significa ejecutar lo que está dentro de los paréntesis en una subshell y devolverlo como un valor , en su caso asignándolo a varible.

bagazo
fuente