Как отобразить пустые фигурные скобки JSON в качестве значения по умолчанию?

11

Похоже, я не могу получить пустой JSON, {}если отсутствует envvar. У меня либо есть трейлинг }на выходе, если он установлен, либо экранирование.

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

Как мне избежать этого правильно?

Ник Т
источник
Интересно, но с bash 4.3 echo "${X:-{\}}"работал просто отлично.
Сергей Колодяжный
@SergiyKolodyazhnyy Это было исправлено в 4.2; Я вспоминаю некоторые дискуссии о цитировании расширений слов после операторов расширения параметров в соответствии со стандартом POSIX.
chepner

Ответы:

14

Цитируйте свои фигурные скобки:

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

Здесь нужны внутренние двойные кавычки, что выглядит забавно, но синтаксически прекрасно.

Одиночные кавычки не будут работать, и я не совсем уверен, почему нет. Это реальное вложенное цитирование, а не конец-и-возобновление, которое вы можете проверить, вставив пробелы. Хотя Double будет работать нормально.

Майкл Гомер
источник
Я думаю, что это соответствующее предложение из спецификации POSIX: «Символ '}', который ограничивает следующие модификации расширения параметров, должен быть определен, как описано ранее в этом разделе и в двойных кавычках». Я интерпретирую это как означающее, что wordследующее :-должно быть специально заключено в двойные кавычки, поэтому "${X:-'{}'}"буквально ${X:-'{}следует '}. Почему спецификация такая конкретная, мне неясно.
chepner
(Предложение, упомянутое «описанным ранее», звучит так: «Соответствующая закрывающая скобка должна быть определена путем подсчета уровней скобок, пропуска заключенных в кавычки строк и подстановок команд».)
chepner
9

Вы можете обмануть и установить переменную равной пустому результату, и избежать проблем с цитированием

$ def="{}"
$ echo ${X:-$def}
{}
$ X=y
$ echo ${X:-$def}
y
$ unset X
$ echo ${X:-$def}
{}
$ 
Стивен Харрис
источник
5

Я часто использую шестнадцатеричные значения для символов через printf:

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

Немного многословно, но работает без особого акцента на кавычки.

Сергей Колодяжный
источник