Jak wyświetlić echo pustych nawiasów klamrowych JSON jako wartość domyślną?

12

Nie mogę wydać pustego JSON, {}aby echo, jeśli brakuje envvara. Mam ciąg końcowy }w danych wyjściowych, jeśli jest ustawiony, lub wyświetla się znaki specjalne .

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

Jak poprawnie go uciec?

Nick T.
źródło
Ciekawe, ale z bash 4.3 echo "${X:-{\}}"działało dobrze.
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy Zostało to naprawione w 4.2; Przypominam sobie dyskusję na temat cytowania rozwinięć słów następujących po operatorach interpretacji parametrów, aby zachować zgodność ze standardem POSIX.
chepner

Odpowiedzi:

14

Podaj swoje szelki:

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

Wewnętrzne podwójne wymagane są tu cytaty, które wygląda śmiesznie, ale jest składniowo porządku.

Pojedyncze cytaty nie będą działać i nie jestem całkowicie pewien, dlaczego nie. To prawdziwe zagnieżdżone cytowanie, a nie koniec i wznowienie, które można zweryfikować, wstawiając spacje. Double będzie jednak działać dobrze.

Michael Homer
źródło
Myślę, że jest to odpowiednie zdanie ze specyfikacji POSIX: „Znak„} ”, który ogranicza następujące modyfikacje rozszerzenia parametrów, należy określić zgodnie z opisem w tej sekcji oraz w cudzysłowach.” Interpretuję to jako oznaczające, że wordponiższe :-cytaty muszą być wyraźnie cytowane, więc "${X:-'{}'}"dosłownie ${X:-'{}następuje '}. Dlaczego specyfikacja jest tak specyficzna, nie jest dla mnie jasne.
chepner
(Zdanie, o którym mowa w „opisanym wcześniej”, brzmi: „Nawias zamykający pasujący zostanie określony przez zliczenie poziomów nawiasów, pominięcie załączonych cytowanych ciągów i zastąpienie poleceń.”)
chepner
9

Możesz oszukiwać i ustawiać zmienną jako pusty wynik i unikać problemów z cytowaniem

$ def="{}"
$ echo ${X:-$def}
{}
$ X=y
$ echo ${X:-$def}
y
$ unset X
$ echo ${X:-$def}
{}
$ 
Stephen Harris
źródło
5

Często używam wartości szesnastkowych znaków poprzez printf:

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

Nieco gadatliwy, ale działa bez nadmiernego stresowania się cytatami.

Sergiy Kolodyazhnyy
źródło