Comment puis-je faire écho à des accolades JSON vides comme valeur par défaut?

11

Je n'arrive pas à faire {}écho un JSON vide si un envvar est manquant. J'ai soit une fuite }dans la sortie si elle est définie, soit l'échappement s'affiche.

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

Comment puis-je y échapper correctement?

Nick T
la source
Intéressant, mais avec bash 4.3 echo "${X:-{\}}"a très bien fonctionné.
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy Cela a été corrigé dans 4.2; Je me souviens d'une discussion sur la citation des extensions de mots suivant les opérateurs d'extension de paramètres pour se conformer à la norme POSIX.
chepner

Réponses:

14

Citez vos bretelles:

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:-"{}"}"
{}

Inner doubles guillemets sont nécessaires ici, qui a l' air drôle , mais est syntaxiquement bien.

Les guillemets simples ne fonctionneront pas, et je ne sais pas pourquoi. Il s'agit de véritables citations imbriquées, pas de fin et de reprise, que vous pouvez vérifier en insérant des espaces. Double fonctionnera bien cependant.

Michael Homer
la source
Je pense que c'est la phrase pertinente de la spécification POSIX: "Le caractère '}' qui délimite les modifications d'expansion de paramètres suivantes doit être déterminé comme décrit précédemment dans cette section et dans Double-Quotes." J'interprète cela comme signifiant que ce qui wordsuit :-doit être spécifiquement entre guillemets, il "${X:-'{}'}"est donc littéralement ${X:-'{}suivi de '}. La raison pour laquelle la spécification est si spécifique n'est pas claire pour moi.
chepner
(La phrase mentionnée par «décrit précédemment» est «L'entretoise de fermeture correspondante doit être déterminée en comptant les niveaux d'accolade, en sautant les chaînes entre guillemets fermées et en remplaçant les commandes.»)
chepner
9

Vous pouvez tricher et définir une variable comme résultat vide et éviter les problèmes de citation

$ def="{}"
$ echo ${X:-$def}
{}
$ X=y
$ echo ${X:-$def}
y
$ unset X
$ echo ${X:-$def}
{}
$ 
Stephen Harris
la source
5

Ce que je fais souvent, c'est utiliser des valeurs hexadécimales pour les caractères via printf:

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

Légèrement verbeux, mais fonctionne sans trop insister sur les citations.

Sergiy Kolodyazhnyy
la source