Una respuesta de StackOverflow con> 3.5K votos presenta esta línea para asignar al DIR
directorio del script bash actual:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
Estoy desconcertado por las comillas dobles anidadas. Por lo que puedo decir, los siguientes fragmentos están entre comillas dobles:
"$( cd "
"${BASH_SOURCE[0]}"
" && pwd )"
... y todo lo demás a la derecha de =
(es decir, $( dirname
y )
) no está entre comillas. En otras palabras, supongo que los caracteres segundo, cuarto y sexto "
"cierran" los caracteres primero, tercero y quinto "
, respectivamente.
Entiendo lo que "${BASH_SOURCE[0]}"
logran las comillas dobles , pero ¿cuál es el propósito de los otros dos pares de comillas dobles?
Si, por otro lado (y a pesar del alto puntaje de voto), el fragmento anterior es incorrecto, ¿cuál es la forma correcta de lograr su intención nominal?
(Por intención nominal quiero decir: recopilar el valor devuelto por pwd
después de primero cd
en el directorio devuelto por dirname "${BASH_SOURCE[0]}"
, y hacer el cd
-ing en un sub-shell, para que el $PWD
del shell principal permanezca sin cambios).
$( here, it's a subshell, but you are writing code as if you were writing it on the "first level" of the shell .... )
.lsb_dist="$(. /etc/os-release && echo "$ID")"; echo "$lsb_dist"
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
funciona.Respuestas:
Su acertijo no es correcto acerca de cómo
bash
(y el shell en general) analizó la entrada. En:Primero,
bash
analice el lado derecho de la asignación a una cadena larga$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
porque la comilla doble puede aparecer dentro de las comillas dobles .Después de eso,
bash
comience a analizar la sustitución del comando. Debido a que todos los caracteres que siguen al paréntesis abierto al paréntesis adjunto se usan para construir el comando dentro de la sustitución del comando, obtendrá:El shell continúa analizando ese comando compuesto, divídalo en dos partes:
cd "$( dirname "${BASH_SOURCE[0]}" )"
Luego, aplica la misma regla de análisis
cd "$( dirname "${BASH_SOURCE[0]}" )"
, pero esta vez, las comillas dobles no son redundantes, pero tienen sentido. Evitan la división de campos en función del resultado$( dirname "${BASH_SOURCE[0]}" )
y también la expansión de${BASH_SOURCE[0]}
(En contraste con las comillas dobles más externas, no será necesario en RHS de asignación de variables para prevenirsplit+glob
).Esta regla se aplica a la sustitución de comandos en todos los shell POSIX . Puede encontrar un rompecabezas más detallado en la sección de Reconocimiento de tokens de la especificación POSIX .
fuente
Una vez que uno está adentro
$(...)
, las citas comienzan desde cero.En otras palabras,
"..."
y$(...)
pueden anidar uno dentro del otro. La sustitución de procesos$(...)
, puede contener una o más cadenas completas entre comillas dobles. Además, las cadenas entre comillas dobles pueden contener una o más sustituciones de proceso completas . Pero no se entrelazan. Por lo tanto, una cadena de comillas dobles que comienza dentro de una sustitución de proceso nunca se extenderá fuera de ella o viceversa.Entonces, considere:
Dentro del interior
$(...)
está:En lo anterior
${BASH_SOURCE[0]}
se cita doblemente. Cualquier comilla, doble o simple, fuera de la,$(...)
es irrelevante al determinar que${BASH_SOURCE[0]}
se cita entre comillas dobles.El exterior
$(...)
contiene:Aquí, la expresión
$( dirname "${BASH_SOURCE[0]}" )
está entre comillas dobles. El hecho de que haya citas fuera del exterior$(...)
es irrelevante cuando se considera lo que está dentro de él. El hecho de que haya citas dentro de lo interno$(...)
también es irrelevante.Así es como coinciden las comillas dobles:
fuente
irrelevant
? Excepto por el paréntesis más externo, todos los demás tienen su propio significado.$(...)
une más fuerte que"..."
" no tiene sentido. No son operadores infijos, y no hay jerarquía entre ellos (si lo hubiera, significaría que las comillas no pueden estar entre paréntesis o los paréntesis no pueden estar entre comillas, pero ese no es el caso). El término técnico es eso$(…)
y"…"
nido.