Czy „$ {PS1-}” jest poprawną składnią i czym różni się od zwykłego „$ PS1”?

12

Patrzę na skrypt, który ma:

if [ "${PS1-}" ]; then

To ostatnie -mnie trochę wkurza, ponieważ wydaje się, że nie jest to standardowa składnia Posix lub Bash. To jakaś tajemnicza składnia, która istnieje od zawsze, czy to literówka? Wszelkie odniesienia do standardów / dokumentów będą mile widziane.

Normalnie kodowałbym to:

if [ "$PS1" ]; then

Co jest bardziej poprawne, czy jest między nimi różnica?

Gregor
źródło

Odpowiedzi:

12

Jest to zdecydowanie składnia POSIX . Parafrazowanie:

Używanie ${parameter-word}, jeśli parameterjest

  • ustawiony i niezerowy, wówczas zastąpić wartość parameter,
  • ustaw, ale null, następnie podstaw null, i
  • rozbrojony, a następnie zamień word.

Przykładowa sesja:

$ echo "${parameter-word}"
word
$ parameter=
$ echo "${parameter-word}"

$ parameter=value
$ echo "${parameter-word}"
value

„Null” oznacza tutaj po prostu pusty ciąg. W przeciwieństwie do SQL, w powłokach POSIX nie ma specjalnej wartości null.

Jest to również udokumentowane w sekcji „Rozszerzanie parametrów” w man bash.

l0b0
źródło
1
Wydaje mi się, że strony podręcznika bash i dash są niekompletne, ponieważ nie wspominają o tej składni (dziwne)!
Gregor
1
@Gregor W obu instrukcjach wspomniano o tym. W podręczniku Bash znajduje się w akapicie przed listą rozszerzeń parametrów, aw podręczniku Dash w akapicie po.
Kusalananda
1
OK, „Pomijając dwukropek ....” Nie widziałem tego :(
Gregor
zshjest jedyną znaną mi powłoką, która wyraźnie wspomina o wariantach wolnych od okrężnicy, a nie tylko odnotowuje, co robi pominięcie okrężnicy.
chepner
1
@pts, tekst w POSIX prawie wyłącznie używa terminu „null”, co może wyjaśniać jego użycie na stronach podręcznika man.
ilkkachu
23

Rozwinięcie zmiennej ${parameter:-word}wykorzysta wartość $parameterif, jeśli jest ustawiona i różna od null (nie jest pustym łańcuchem), w przeciwnym razie użyje łańcucha word.

Pominięcie tej opcji :nie sprawdzi, czy wartość jest pusta, tylko czy jest nieustawiona, czy nie.

Oznacza to, że ${PS1-}rozwinie się do wartości, $PS1jeśli jest ustawiona, ale do pustego ciągu, jeśli jest pusta lub rozbrojona. W tym przypadku jest to dokładnie to samo, co ${PS1:-}ciąg po -jest również pusty.

Różnica między "${PS1-}"i "$PS1"jest subtelna, jak zauważa @Rakesh Sharma: oba rozwiną się do wartości $PS1lub do pustego ciągu, jeśli nie jest ustawiony. Wyjątkiem jest to, kiedy set -ujest aktywny, w którym to przypadku rozwinięcie nieuzbrojonych zmiennych spowoduje błąd . Ustawiona przez (pusta) wartość domyślna pozwala "${PS1-}"to obejść, rozszerzając unset PS1do pustego ciągu bez błędu.

Jest to standardowa składnia ( pochodząca z powłoki Bourne'a pod koniec lat 70. ), podobnie jak kilka innych podobnych rozszerzeń.

Kusalananda
źródło
A ponieważ był cytowany, jest taki sam "$PS1", ponieważ jeśli PS1jest pusty, jest pusty, a cytaty uniemożliwiają całkowite zniknięcie słowa.
ilkkachu
4
Tak długo, jak set -unie działa. Gdy opcja rzeczownika jest włączona, wówczas „$ PS1” => daje błąd. „$ {PS-}” nie będzie.
@RakeshSharma to dobry punkt. Różna składnia może w rzeczywistości dawać różne wyniki w zależności od opcji rzeczownika, więc test ["$ {parameter-}"] jest prawdopodobnie bardziej poprawny!
Gregor
1
@Kusalananda: Pamiętaj, że ${parameter:-word}użyje wartości, $parameterjeśli nie jest NULL. We wszystkich innych przypadkach (co oznacza: albo ustawione, ale NULL lub nieuzbrojone) użyje word. Twoje sformułowanie:if its set or null
@ikkachu: Tak, to prawda. Tylko wtedy, gdy zmienne są set AND nonnull=> użyj samego. W przeciwnym razie ( set but NULL OR unset) => użyj słowa.
6

Składnia:

${parameter:-word}

i specjalny formularz:

${parameter-word}

jest poprawną składnią w powłoce POSIX , oznacza użycie wartości domyślnej, wordjeśli parameterjest nieustawiona lub zerowa.


Zwykle z wordjest puste, a następnie:

${parameter-}

i:

$parameter

lub:

${parameter}

są równoważne.

Ale pod wpływem set -uwszystkich nieustawionych zmiennych powoduje zakończenie powłoki. ${parameter-}służy do ominięcia tej ścisłej zasady. Działa w obu przypadkach, więc tak, jest to bardziej poprawny sposób.

Cuonglm
źródło