Como ecoar um colchete JSON vazio como valor padrão?


11

Não consigo obter um JSON vazio {}para ecoar se estiver faltando um envvar. Ou tenho um rastro }na saída, se definido, ou a fuga é exibida.

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

Como faço para escapar corretamente?


Interessante, mas com o bash 4.3 echo "${X:-{\}}"funcionou muito bem.
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy Isso foi corrigido no 4.2; Lembro-me de uma discussão sobre a citação de expansões de palavras, seguindo operadores de expansão de parâmetros para estar em conformidade com o padrão POSIX.
Chepner #

Respostas:


14

Cite seus aparelhos:

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

As aspas duplas internas são obrigatórias aqui, o que parece engraçado, mas é sintaticamente correto.

As aspas simples não funcionam, e não sei bem por que não. Essa é uma citação aninhada real, não final e resumo, que você pode verificar colocando espaços. No entanto, o Double funcionará bem.


Penso que esta é a sentença relevante da especificação POSIX: "O caractere '}' que delimita as seguintes modificações de expansão de parâmetros deve ser determinado conforme descrito anteriormente nesta seção e entre aspas duplas." Eu interpreto isso como significando que o wordseguinte :-deve ser especificamente entre aspas duplas, portanto "${X:-'{}'}"é literalmente ${X:-'{}seguido por '}. Por que a especificação é tão específica não está clara para mim.
Chepner #

(A sentença mencionada por "descrito anteriormente" é "A chave de fechamento correspondente será determinada pela contagem dos níveis da chave, passando por cima das strings entre aspas e substituindo comandos.")
chepner

9

Você pode trapacear e definir uma variável para ser o resultado vazio e evitar os problemas de cotação.

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

5

O que frequentemente faço é usar valores hexadecimais para caracteres via printf:

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

Um pouco detalhado, mas funciona sem muito estresse sobre as aspas.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.