Wie erhält man einen Variablenwert, wenn der Variablenname als String gespeichert wird?

Wie kann ich einen Bash-Variablenwert abrufen, wenn ich den Variablennamen als String habe?

var1="this is the real value" a="var1" Do something to get value of var1 just using variable a. 

Kontext:

Ich habe einige AMIs ( Amazon Machine Image ) und ich möchte ein paar Instanzen von jedem AMI starten. Sobald sie mit dem Booten fertig sind, möchte ich jede Instanz entsprechend ihrem AMI-Typ einrichten. Ich möchte nicht viele Skripte oder geheime Schlüssel in irgendeinem AMI brennen, also habe ich ein generalisiertes Startskript vorbereitet und es auf S3 mit einem öffentlich zugänglichen Link gesetzt. In rc.local habe ich einen kleinen Code eingefügt, der das Startskript holt und ausführt. Das ist alles was ich in den AMIs habe. Dann greift jedes AMI auf ein gemeinsames Konfigurationsskript zu, das für alle AMIs und spezielle Setup-Skripte für jedes AMI anwendbar ist. Diese Skripts sind privat und benötigen eine signierte URL, um auf sie zuzugreifen.

Wenn ich jetzt eine Instanz eines AMI (my_private_ami_1) feuere, übergebe ich eine signierte URL für eine weitere Datei, die in S3 präsentiert wird und eine signierte URL für alle privaten Skripte in Bezug auf das Schlüssel / Wert-Paar enthält.

 config_url="http://s3.amazo.../config?signature" my_private_ami_1="http://s3.amazo.../ami_1?signature" ... 

Wenn das Startscript ausgeführt wird, lädt es die obige Datei und die source herunter. Dann prüft es auf seinen AMI-Typ und wählt das richtige Setup-Skript für sich aus.

 ami\_type=GET AMI TYPE #ex: sets ami\_type to my\_private\_ami\_1 setup\_url=GET THE SETUP FILE URL BASED ON AMI\_TYPE # this is where this problem arises 

Jetzt kann ich einen generischen Code haben, der Instanzen unabhängig von ihren AMI-Typen auslösen kann und Instanzen können auf sich selbst aufpassen.

   

Sie können ${!a} .

Dies ist ein Beispiel für die indirekte Parametererweiterung :

Die grundlegende Form der Parametererweiterung ist ${parameter} . Der Wert des parameter ist substituiert.

Wenn das erste Zeichen des parameter ein Ausrufezeichen (!) Ist, wird eine Ebene der Variablenindirektion eingeführt. Bash verwendet den Wert der aus dem Rest des parameter gebildeten Variablen als Namen der Variablen; Diese Variable wird dann erweitert, und dieser Wert wird im Rest der Substitution anstelle des Werts des parameter selbst verwendet.

 X=foo Y=X eval "Z=\$$Y" 

setzt Z auf “foo”

Seien Sie vorsichtig bei der Verwendung von eval da dies eine unbeabsichtigte Ausgabe von Code durch Werte in ${Y} . Dies kann zu Schäden durch Code-Injektion führen.

Beispielsweise

 Y="\`touch /tmp/eval-is-evil\`" 

würde /tmp/eval-is-evil erstellen. Das könnte natürlich auch etwas rm -rf / .

Meine Suchbegriffe geändert und es geschafft :).

 eval a=\$$a 

Vielen Dank für Ihre Zeit.

Für meine anderen zsh-Benutzer besteht die Möglichkeit, dasselbe wie die akzeptierte Antwort zu erreichen, wie folgt:

${(P)a}

Es heißt Parametername Ersatz

Dies erzwingt, dass der Wert des Parameternamens als ein weiterer Parametername interpretiert wird, dessen Wert gegebenenfalls verwendet wird. Beachten Sie, dass Flags, die mit einer der typisierten Befehlssätze (insbesondere Transformationen) gesetzt wurden, nicht auf den Wert des Namens angewendet werden, der auf diese Weise verwendet wird.

Bei Verwendung mit einem geschachtelten Parameter oder einer Befehlsersetzung wird das Ergebnis davon auf die gleiche Weise als Parametername verwendet. Wenn Sie beispielsweise ‘foo = bar’ und ‘bar = baz’ haben, sind die Strings $ {(P) foo}, $ {(P) $ {foo}} und $ {(P) $ (echo bar) } wird zu ‘baz’ erweitert.

Wenn der Verweis selbst verschachtelt ist, wird der Ausdruck mit dem Flag genauso behandelt, als ob er direkt durch den Parameternamen ersetzt würde. Es ist ein Fehler, wenn diese verschachtelte Substitution ein Array mit mehr als einem Wort erzeugt. Zum Beispiel, wenn ‘name = assoc’ wo der Parameter assoc ein assoziatives Array ist, dann bezieht sich ‘$ {$ {(P) name} [elt]}’ auf das Element des assoziativen subskribierten ‘elt’.

Moderne Shells unterstützen bereits Arrays (und sogar assoziative Arrays). Also bitte benutze sie und benutze weniger von eval.

 var1="this is the real value" array=("$var1") # or array[0]="$var1" 

Wenn Sie es dann aufrufen möchten, echo $ {array [0]}