2016-07-01 5 views
0

ich eine Reihe von Variablen zu überprüfen, und eine Reihe von Standardwerten wie folgt:Überprüfen Sie, ob Variablen gesetzt sind, und Attribut einen Standard sonst

variables_to_check="name surname address" 
variables_default_values="John Doe Paris" 

Hier ist, was ich tun möchte:

  1. überprüfen sie, ob $ name gesetzt ist, wenn nicht, geben sie John als Wert
  2. überprüfen sie, ob $ Namen gesetzt ist, wenn nicht, geben Doe als Wert
  3. ...
  4. Hier

ist der aktuelle nicht-funktionierenden Code ich habe:

variables_to_check="name surname address" 
variables_default_values="John Doe Paris" 
i=0 
for variable in $variables_to_check 
do 
    ((i++)) 
    if [[ -z ${"$variable"+x} ]] #this line doesn't seem to work 
           #inspired from http://stackoverflow.com/questions/3601515 
    then 
     default=$(echo $variables_default_values | cut -d " " -f $i) 
     set_config $variable $default 
     declare "$variable=$default" #this doesn't seem to work either 
            #inspired from http://stackoverflow.com/questions/16553089 
    fi 
done 

Jede Hilfe willkommen wäre stark

+0

Welche Version von 'bash' können Sie benutzen? – chepner

+0

Ich laufe zur Zeit 'bash' Version' 4.3.30', aber das System wird auf dem neuesten Stand gehalten - das heißt, ich kann die neuste Version von 'bash' bei Bedarf verwenden – Magix

+0

Siehe' $ {! Variable} 'unter Bash [Shell-Parameter-Erweiterungen] (https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion). –

Antwort

1

Sie können "namerefs", dies zu tun:

variables=(a b c d e) 
c=1 
d=7 

value=42 

declare -n var 

for var in ${variables[@]}; do 
    if [[ ! -v var ]]; then 
     var=$value 
    fi 
done 

echo $a, $b, $c, $d, $e 

es Laufen:

$ bash script.sh 
42, 42, 1, 7, 42 

Innerhalb der Schleife das var Variable ist ein Name Bezug auf das in dem Array mit dem Namen Variablen variables was bedeutet, dass Sie varals die benannte Variable verwenden können.

Verwenden Sie -v, um festzustellen, ob die Variable festgelegt ist oder nicht, und wenn nicht, weisen Sie ihr einen Wert zu.Die gesamte if-Anweisung kann auch mit der einzigen Linie

: ${var:=$value} 

(die : ist ein No-op-Befehl, die Argumente auswertet und die Auswertung des Arguments hat den Nebeneffekt, dass die Schale einen Wert zuweist ersetzt werden auf die Variable var, wenn es nicht gesetzt ist).

EDIT: Das Folgende ist die gleiche Sache, aber mit getrennten Standardwerte für jede der Variablen:

variables=(a b c d e) 
defaults=(1 2 3 4 5) 

c=1 
d=7 

for ((i = 0; i < ${#variables[@]}; ++i)); do 
     declare -n var="${variables[$i]}" 
     value="${defaults[$i]}" 

     : ${var:=$value} 
done 

echo $a, $b, $c, $d, $e 

es Laufen:

$ bash script.sh 
1, 2, 1, 7, 5 
+0

wow, sehr nest Trick mit ':'. Es funktioniert jedoch nur, wenn nur ein Standardwert benötigt wird und nicht wenn ein ganzes Array von Standardwerten verwendet werden soll. – Magix

+0

@Magix Nun, das ist, wofür wir die Schleife verwenden :-) – Kusalananda

+0

Was ich meine ist, was ist, wenn ich verschiedene Standardeinstellungen für 'a',' b', 'c',' d', 'e' und' f '? Der ':' Trick wird unbrauchbar, oder? – Magix

1

Verwenden -v Operator, um zu bestimmen, ob eine Variable gesetzt ist. Dies ist auch viel einfacher, wenn Sie Arrays zum Speichern der Namen und Standardwerte verwenden.

variables=(name surname address) 
default_values=(John Doe "somewhere in Paris") 

for ((i=0; i < ${#variables[@]}; i++)); do 
    if ! [[ -v ${variables[i]} ]]; then 
     declare "${variables[i]}=${default_values[i]}" 
    fi 
done 

bash 4,3 oder höher für -v erforderlich mit Arrays zu arbeiten.

Namerefs (auch in 4.3 eingeführt) kann dies ein wenig einfacher machen:

for ((i=0; i < ${#variables[@]}; i++)); do 
    declare -n name=${variables[i]} 
    [[ -v name ]] && name=${default_values[i]}" 
done 

Es sei denn, die Variable und Standardwertelisten programmatisch erzeugt werden, ein wenig Überschneidungen besser lesbar viel sein wird und nicht wirklich härter zu erhalten:

# This will also work in any POSIX-compliant shell, not just 
# in a sufficiently new version of bash 
: ${name:=John} 
: ${surname:=Doe} 
: ${address:=somewhere in Paris} 
0

Die Shell einige schöne String-Ersetzung Operatoren hat, die das tun, aber es gibt Ihnen eine dritte Möglichkeit nicht oben aufgeführte Liste: Variable wird „“ zu schätzen.

Expression  "var Set not Null" "var Set but Null" "var Unset" 
${var-DEFAULT}  var     null    DEFAULT  
${var:-DEFAULT}  var     DEFAULT   DEFAULT 
${var=DEFAULT}  var     null    DEFAULT  
${var:=DEFAULT}  var     DEFAULT   DEFAULT  
${var+OTHER}  OTHER    OTHER   null 
${var:+OTHER}  OTHER    null    null 

Also in Ihrem Fall würden Sie so etwas wie:

${name:-"John"} # or ${name:="John"} 
${surname:-"Doe"} # or ${surname:="Doe"} 

und so weiter.