¿Es válida la sintaxis válida "$ {PS1-}" y en qué se diferencia de la simple "$ PS1"?


12

Estoy viendo un script que tiene:

if [ "${PS1-}" ]; then

Eso -me molesta un poco porque no parece la sintaxis estándar de Posix o Bash. ¿Es esta una sintaxis arcana que ha existido desde siempre, o es un error tipográfico? Cualquier referencia a estándares / documentos sería apreciada.

Normalmente lo codificaría:

if [ "$PS1" ]; then

¿Cuál es más correcto o hay una diferencia entre ellos?

Respuestas:


12

Esta es definitivamente la sintaxis POSIX . Parafraseando:

Usando ${parameter-word}, si parameteres

  • establecer y no nulo, luego sustituir el valor de parameter,
  • establecer pero nulo, luego sustituir nulo y
  • desarmar, luego sustituir word.

Sesión de ejemplo:

$ echo "${parameter-word}"
word
$ parameter=
$ echo "${parameter-word}"

$ parameter=value
$ echo "${parameter-word}"
value

"Nulo" aquí simplemente significa la cadena vacía. No hay un valor nulo especial en shells POSIX, en contraste con SQL, por ejemplo.

Esto también está documentado en la sección "Expansión de parámetros" de man bash.


1
¡Supongo que las páginas de manual de bash y dash están incompletas, porque no mencionan esta sintaxis (impar)!
Gregor

1
@ Gregor Ambos manuales mencionan esto. En el manual de Bash está en el párrafo anterior a la lista de expansiones de parámetros, y en el manual de Dash está en el párrafo siguiente.
Kusalananda

1
OK, "Omitiendo el colon ..." No vi eso :(
Gregor

zshes el único shell que conozco que menciona explícitamente las variantes libres de colon, en lugar de simplemente hacer una nota de lo que hace omitir el colon.
chepner

1
@pts, el texto en POSIX usa casi exclusivamente el término "nulo", lo que podría explicar su uso en las páginas de manual.
ilkkachu

23

La expansión variable ${parameter:-word}usará el valor de $parametersi está establecido y no es nulo (no es una cadena vacía), de lo contrario usará la cadena word.

Omitir :no probará si el valor está vacío, solo si está desarmado o no.

Esto significa que ${PS1-}se expandirá al valor de $PS1si está configurado, pero a una cadena vacía si está vacío o sin configurar. En este caso, esto es exactamente lo mismo que ${PS1:-}como la cadena después -también está vacía.

La diferencia entre "${PS1-}"y "$PS1"es sutil, como señala @Rakesh Sharma: ambos se expandirán al valor de $PS1, o a una cadena vacía si no está establecida. La excepción es cuando set -uestá activo, en cuyo caso expandir las variables no definidas causaría un error . El valor predeterminado (vacío) establecido por "${PS1-}"evita esto, expandiendo un desarmado PS1a la cadena vacía sin error.

Esta es la sintaxis estándar ( originada en el shell Bourne a finales de los 70 ), al igual que otras expansiones similares.


Y dado que fue citado, es lo mismo que "$PS1", si PS1está vacío, está vacío, y las comillas evitan que la palabra desaparezca por completo.
ilkkachu

44
Mientras set -uno esté en vigor. Cuando la opción nounset está activada, entonces "$ PS1" => da error. "$ {PS-}" no lo hará.

@RakeshSharma que es un buen punto. La sintaxis diferente en realidad puede producir resultados diferentes dependiendo de la opción de sustantivo, por lo tanto, la prueba ["$ {parámetro-}"] es probablemente más correcta.
Gregor

1
@Kusalananda: Tenga en cuenta que ${parameter:-word}usará el valor de $parametersi es NO NULL. En todos los demás casos (es decir: establecido pero NULL o no establecido) se utilizará word. Su redacción:if its set or null

@ikkachu: Sí, eso es correcto. Solo cuando las variables son set AND nonnull=> se usan a sí mismas. De lo contrario, ( set but NULL OR unset) => usan palabras.

6

La sintaxis:

${parameter:-word}

y una forma especial:

${parameter-word}

es la sintaxis válida en el shell POSIX , significa usar el valor predeterminado wordsi no parameterestá configurado o es nulo.


Normalmente, con wordestá vacío, entonces:

${parameter-}

y:

$parameter

o:

${parameter}

son equivalentes

Pero bajo el efecto de set -u, todas las variables no configuradas hacen que se termine el shell. ${parameter-}se usa para saltarse esa estricta regla. Funciona en ambos casos, así que sí, es la forma más correcta.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.