Zuweisen von Standardwerten zu Shell-Variablen mit einem einzigen Befehl in bash

682

Ich habe eine ganze Reihe von Tests für Variablen in einem Bash (3.00) -Shell-Skript, bei denen, wenn die Variable nicht festgelegt ist, eine Standardeinstellung zugewiesen wird, z.

if [ -z "${VARIABLE}" ]; then 
    FOO='default'
else 
    FOO=${VARIABLE}
fi

Ich erinnere mich an eine Syntax in einer Zeile, die einem ternären Operator ähnelt, z.

FOO=${ ${VARIABLE} : 'default' }

(obwohl ich weiß, dass das nicht funktioniert ...)

Bin ich verrückt oder gibt es so etwas?

Edward Q. Bridges
quelle
1
Der Abschnitt zur Erweiterung der Shell-Parameter der Bash-Shell-Referenz ist ein guter Ausgangspunkt: tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions .
Kemin Zhou
1
Gnu.org Dokumentation für Shell Parameter Expansion (Hinweis: Es gibt viele andere coole Sachen, die Sie tun können!)
JDB erinnert sich noch an Monica

Antworten:

1224

Ganz in der Nähe von dem, was Sie gepostet haben:

FOO=${VARIABLE:-default}  # If variable not set or null, use default.

Oder wird zuzuordnen , die defaultzu VARIABLEauch:

FOO=${VARIABLE:=default}  # If variable not set or null, set it to default.
Andrew McGregor
quelle
64
Wenn ich dies in der Dokumentation finden wollte, wofür würde Google gehen? Mit Sonderzeichen wie $ {: -} zu googeln ist nicht sehr einfach.
Joshua Olson
20
Als Antwort auf den Solarmisten: "Bash-Variablenzuweisungsstandard", lassen Sie mich auf diese Seite gehen, und das Durchsuchen der Bash-Handbuchseite mit 'variabler Arsch' brachte mich nach ~ fünf 'Nächsten'
Mooshu
57
Beachten Sie, dass es nicht bash-spezifisch ist und mit der gesamten Shell-Familie funktioniert. Es ist sicher für generische Skripte.
Jocelyn delalande
16
@solarmist Das Schlüsselwort ist "Bash-Parametererweiterung", wenn Sie mehr darüber und über seine Begleiter erfahren möchten.
Duleshi
20
Hier ist eine ausführlichere Erklärung zum Thema unix.stackexchange.com/a/122848/2407
jottr
288

Für Befehlszeilenargumente:

VARIABLE=${1:-DEFAULTVALUE}    

Dies wird VARIABLEdem Wert des ersten an das Skript übergebenen Arguments oder dem Wert zugewiesen, DEFAULTVALUEwenn kein solches Argument übergeben wurde.

miku
quelle
243

Wenn die Variable gleich ist, dann

: "${VARIABLE:=DEFAULT_VALUE}"

weist VARIABLE DEFAULT_VALUE zu, falls nicht definiert. Die doppelten Anführungszeichen verhindern das Globbing und das Teilen von Wörtern.

Siehe auch Abschnitt 3.5.3, Erweiterung der Shell-Parameter , im Bash-Handbuch.

Hans Ginzel
quelle
27
Dieser knifflige Trick war für mich nicht offensichtlich, da ich den eingebauten: no-effect verwendet habe, um die Erweiterung des $ {..} zu essen, ABER das VARIABLE-Set zu verlassen. Bis jetzt habe ich Folgendes getan: VARIABLE = "$ {VARIABLE: -DEFAULT_VALUE}" und fühlte mich dumm, weil ich VARIABLE zweimal verwendet habe.
Dino
Es stellt sich heraus, dass dies nicht immer für BASH-BUILTIN-VARIABLEN funktioniert. Es ist sehr sehr seltsam. Derzeit sind die mir bekanntenHISTTIMEFORMAT
Otheus
Wie würde ich mehrere Standardwerte festlegen? Ich habe versucht ": $ {VARIABLE: = DEFAULT_VALUE}: $ {VARIABLE2: = DEFAULT_VALUE2}", aber das scheint nicht zu funktionieren ...
Hans
8
@Hans: Der Doppelpunkt ist der Befehl (der nichts tut) und wird daher nur einmal benötigt. ZB: ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
Patrik
34

Auch Sie können als Standardwert den Wert einer anderen Variablen verwenden

eine Datei haben defvalue.sh

#!/bin/bash
variable1=$1
variable2=${2:-$variable1}

echo $variable1
echo $variable2

./defvalue.sh first-value second-valueAusgabe ausführen

first-value
second-value

und ./defvalue.sh first-valueAusgabe ausführen

first-value
first-value
Montells
quelle
27

siehe hier unter 3.5.3 (Shell-Parametererweiterung)

also in deinem Fall

${VARIABLE:-default}
Ghostdog74
quelle
25

Zur Beantwortung Ihrer Frage und zu allen variablen Substitutionen

echo "$\{var}"
echo "Substitute the value of var."


echo "$\{var:-word}"
echo "If var is null or unset, word is substituted for var. The value of var does not change."


echo "$\{var:=word}"
echo "If var is null or unset, var is set to the value of word."


echo "$\{var:?message}"
echo "If var is null or unset, message is printed to standard error. This checks that variables are set correctly."


echo "$\{var:+word}"
echo "If var is set, word is substituted for var. The value of var does not change."
Guru
quelle
17

FWIW, Sie können eine Fehlermeldung wie folgt eingeben:

USERNAME=${1:?"Specify a username"}

Dies zeigt eine Meldung wie diese an und wird mit Code 1 beendet:

./myscript.sh
./myscript.sh: line 2: 1: Specify a username

Ein vollständigeres Beispiel für alles:

#!/bin/bash
ACTION=${1:?"Specify 'action' as argv[1]"}
DIRNAME=${2:-$PWD}
OUTPUT_DIR=${3:-${HOMEDIR:-"/tmp"}}

echo "$ACTION"
echo "$DIRNAME"
echo "$OUTPUT_DIR"

Ausgabe:

$ ./script.sh foo
foo
/path/to/pwd
/tmp

$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
  • $ACTION Nimmt den Wert des ersten Arguments und wird beendet, wenn es leer ist
  • $DIRNAME ist das 2. Argument und verwendet standardmäßig das aktuelle Verzeichnis
  • $OUTPUT_DIRist das 3. Argument oder $HOMEDIR(falls definiert) sonst , /tmp. Dies funktioniert unter OS X, aber ich bin mir nicht sicher, ob es portabel ist.
Curtis Mattoon
quelle
16

Dann gibt es die Möglichkeit, Ihr "Wenn" -Konstrukt knapper auszudrücken:

FOO='default'
[ -n "${VARIABLE}" ] && FOO=${VARIABLE}
Rob Wells
quelle
9

Hier ist ein Beispiel

#!/bin/bash

default='default_value'
value=${1:-$default}

echo "value: [$value]"

Speichern Sie dies als script.sh und machen Sie es ausführbar. Führen Sie es ohne Parameter aus

./script.sh
> value: [default_value]

Führen Sie es mit param aus

./script.sh my_value
> value: [my_value]
Assaf Shomer
quelle