¿Cómo hago eco de una llave JSON vacía como valor predeterminado?


11

Parece que no puedo obtener un JSON vacío {}para hacer eco si falta un envvar. O tengo un seguimiento }en la salida si está configurado, o se muestra el escape.

bash-3.2$ unset X
bash-3.2$ echo "${X:-{}}"
{}
bash-3.2$ X=y
bash-3.2$ echo "${X:-{}}"
y}
bash-3.2$ echo "${X:-{\}}"
y
bash-3.2$ unset X
bash-3.2$ echo "${X:-{\}}"
{\}
bash-3.2$ echo "${X:-'{}'}"
'{}'
bash-3.2$ X=z
bash-3.2$ echo "${X:-'{}'}"
z

¿Cómo escapo correctamente?


Interesante, pero con bash 4.3 echo "${X:-{\}}"funcionó bien.
— Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy Eso se solucionó en 4.2; Recuerdo algunas discusiones sobre la cita de expansiones de palabras después de operadores de expansión de parámetros para cumplir con el estándar POSIX.
— chepner

Respuestas:


14

Cita tus frenillos:

bash-3.2$ echo "${X:-"{}"}"
{}
bash-3.2$ X=y
bash-3.2$ echo "${X:-"{}"}"
y
bash-3.2$ unset X
bash-3.2$ echo "${X:-"{}"}"
{}

Aquí se requieren comillas dobles internas , lo que parece divertido pero está sintácticamente bien.

Las comillas simples no funcionarán, y no estoy completamente seguro de por qué no. Esta es una cita real anidada, no end-and-resume, que puede verificar colocando espacios. Sin embargo, Double funcionará bien.


Creo que esta es la oración relevante de la especificación POSIX: "El carácter '}' que delimita las siguientes modificaciones de expansión de parámetros se determinará como se describió anteriormente en esta sección y en comillas dobles". Interpreto que esto significa que lo wordsiguiente :-debe estar específicamente entre comillas dobles, por "${X:-'{}'}"lo que literalmente va ${X:-'{}seguido de '}. Por qué la especificación es tan específica no me queda claro.
— chepner

(La frase mencionada por "descrito anteriormente" es "La llave de cierre correspondiente se determinará por los niveles de recuento Brace, saltando sobre las cadenas entre comillas cerradas, y sustituciones de comando.")
— chepner

9

Puede hacer trampa y establecer una variable para que sea el resultado vacío, y evitar los problemas de citas

$ def="{}"
$ echo ${X:-$def}
{}
$ X=y
$ echo ${X:-$def}
y
$ unset X
$ echo ${X:-$def}
{}
$ 

5

Lo que hago con frecuencia es utilizar valores hexadecimales para los caracteres a través de printf:

bash-4.3$ echo "${X:-$(printf '\x7B\x7D')}"
{}
bash-4.3$ X="something"
bash-4.3$ echo "${X:-$(printf '\x7B\x7D')}"
something

Ligeramente detallado, pero funciona sin demasiado estrés sobre las citas.

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.