bash przypisuje wartość domyślną


145

$ {parametr: = słowo} Przypisz wartości domyślne. Jeśli parametr jest nieustawiony lub pusty, interpretacja słowa jest przypisywana do parametru. Wartość parametru jest następnie podstawiana. Nie można w ten sposób przypisywać parametrów pozycyjnych i parametrów specjalnych.

Pomyślałem, że mógłbym użyć tej funkcji do pisania ${LONG_VARIABLE_NAME:=hello}zamiast dłuższego LONG_VARIABLE_NAME=${LONG_VARIABLE_NAME:-hello}, ale teraz bash również próbuje wykonać `` cześć '', a to daje polecenie, którego nie znaleziono. Jakiś sposób, aby tego uniknąć? A może będę musiał trzymać się tego drugiego? Czy ktoś może podać przykład, w którym przypisanie wartości domyślnej jest rzeczywiście przydatne?


16
Cytując tekst, warto dołączyć link do źródła.
Jonathon Reinhart

Odpowiedzi:


215

Użyj dwukropka:

: ${A:=hello}

Dwukropek to puste polecenie, które nic nie robi i ignoruje jego argumenty. Jest wbudowany w bash, więc nie jest tworzony nowy proces.


102
Nie mogę nic na to poradzić, ale zauważam, że : ${A:=hello}jest dokładnie tak długi A=${A:-hello}. Wydaje się też, że ta ostatnia jest trochę mniej ezoteryczna, a jej cel jest wyraźniejszy. Używanie :, które w zasadzie jest no-op, wydaje się niezdarne w porównaniu do sposobu, w jaki OP robił to wcześniej.
Dan Molding,

5
@camh: Zgoda. Widzę, gdzie, gdybyś miał wiele zmiennych do zainicjowania do wartości domyślnych i mają one długie nazwy, takie :podejście byłoby lepsze, zarówno do pisania, jak i do czytania. Tak, wydaje się, że to obszar, w którym Bash przydałby się niewielka poprawa.
Dan Molding

21
@DanMoulding: a co z : ${VERY_LONG_VARIABLE_NAME:=hello}vs VERY_LONG_VARIABLE_NAME=${VERY_LONG_VARIABLE_NAME:-hello}. : . Mam nadzieję, że używasz w swoim kodzie opisowych nazw zmiennych :)
pihentagy

20
Nie tylko krótsze, ale mniej podatne na błędy: VERY_LONG_VARIABLE_NAME=${VERY_LOGN_VARIABLE_NAME:-hello}. Ups.
chepner

5
Zaletą tego A=$A:-hellopodejścia jest to, że samodokumentuje się, gdy jest uruchamiany z set -x. Oznacza to, że przypisanie zostanie wydrukowane jako, A=hellopodczas gdy polecenie null wypisze tylko wartość ( hello).
lmsurprenant

122

Przykłady można znaleźć pod adresem http://www.tldp.org/LDP/abs/html/parameter-substitution.html

${parameter-default}, ${parameter:-default}

Jeśli parametr nie jest ustawiony, użyj wartości domyślnej. Po wywołaniu parametr nadal nie jest ustawiony.
Obie formy są prawie równoważne. Dodatek :robi różnicę tylko wtedy, gdy parametr został zadeklarowany, ale ma wartość null.

unset EGGS
echo 1 ${EGGS-spam}   # 1 spam
echo 2 ${EGGS:-spam}  # 2 spam

EGGS=
echo 3 ${EGGS-spam}   # 3
echo 4 ${EGGS:-spam}  # 4 spam

EGGS=cheese
echo 5 ${EGGS-spam}   # 5 cheese
echo 6 ${EGGS:-spam}  # 6 cheese

${parameter=default}, ${parameter:=default}

Jeśli parametr nie jest ustawiony, ustaw wartość parametru na domyślną.
Obie formy są prawie równoważne. : Robi różnicę tylko wtedy, gdy parametr został zadeklarowany i ma wartość null

# sets variable without needing to reassign
# colons suppress attempting to run the string
unset EGGS
: ${EGGS=spam}
echo 1 $EGGS     # 1 spam
unset EGGS
: ${EGGS:=spam}
echo 2 $EGGS     # 2 spam

EGGS=
: ${EGGS=spam}
echo 3 $EGGS     # 3        (set, but blank -> leaves alone)
EGGS=
: ${EGGS:=spam}
echo 4 $EGGS     # 4 spam

EGGS=cheese
: ${EGGS:=spam}
echo 5 $EGGS     # 5 cheese
EGGS=cheese
: ${EGGS=spam}
echo 6 $EGGS     # 6 cheese

${parameter+alt_value}, ${parameter:+alt_value}

Jeśli parametr jest ustawiony, użyj alt_value, w przeciwnym razie użyj łańcucha null. Po wywołaniu wartość parametru nie uległa zmianie.
Obie formy są prawie równoważne. : Robi różnicę tylko wtedy, gdy parametr został zadeklarowany i ma wartość null

unset EGGS
echo 1 ${EGGS+spam}  # 1
echo 2 ${EGGS:+spam} # 2

EGGS=
echo 3 ${EGGS+spam}  # 3 spam
echo 4 ${EGGS:+spam} # 4

EGGS=cheese
echo 5 ${EGGS+spam}  # 5 spam
echo 6 ${EGGS:+spam} # 6 spam

20

Rozwijanie parametru wartości domyślnej jest często przydatne w skryptach budowania, takich jak przykład poniżej. Jeśli użytkownik wywoła skrypt w takiej postaci, w jakiej jest, perl nie zostanie wbudowany. Użytkownik musi jawnie ustawić WITH_PERLwartość inną niż „nie”, aby został wbudowany.

$ cat defvar.sh
#!/bin/bash

WITH_PERL=${WITH_PERL:-no}

if [[ "$WITH_PERL" != no ]]; then
    echo "building with perl"
    # ./configure --enable=perl
else
    echo "not building with perl"
    # ./configure
fi

Buduj bez Perla

$ ./defvar.sh
not building with perl

Buduj z Perlem

$ WITH_PERL=yes ./defvar.sh
building with perl

0

Możesz także użyć :=konstrukcji, aby przypisać i zdecydować o działaniu w jednym kroku. Rozważ następujący przykład:

# Example of setting default server and reporting it's status

server=$1
if [[ ${server:=localhost} =~ [a-z] ]]      # 'localhost' assigned here to $server
then    echo "server is localhost"          # echo is triggered since letters were found in $server
else
        echo "server was set" # numbers were passed
fi

Jeśli $1nie jest puste, localhostzostanie przypisane serverw polu ifwarunku, wyzwalanie dopasowania i zgłoszenie wyniku dopasowania. W ten sposób możesz przypisać w locie i wywołać odpowiednią akcję.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.