ZB wird das nächste Skript Hello
aufgrund der ${!
Regel gedruckt .
A=B
B=Hello
echo ${!A}
Aber wie kann ich den Wert auf eine Variable mit indirektem Namen setzen? Die einfache Verwendung von !
Zeichen funktioniert nicht:
A=B
!A=Hello # here is tricky line
echo $B
Ich weiß, dass es einen Trick bei der Verwendung von temporären Dateien gibt, aber ich bin daran interessiert, Indirektion zu verwenden, nicht so etwas
A=B
echo "$A=Hello" > 1.tmp
. 1.tmp
echo $B
eval $A=foobar
Antworten:
Ein anderer Weg, den Sie versuchen könnten:
Aber es gibt ein Sicherheitsrisiko (!) Wie bei all diesen Methoden (auch
declare
/typeset
und natürlicheval
). In diesem Fall muss man die linke Seite (den Wert von$A
) kontrollieren , mit anderen Worten, zumindest inbash
sollte Variable$A
nicht enthalten Benutzergesteuerte Eingabe, zum Beispiel eine Eingabedatei usw.Wenn Ihre Shell keine Here-Zeichenfolge (
<<<
) unterstützt, können Sie stattdessen auch ein Here-Dokument verwenden:quelle
Sie können dies mit dem
typeset
eingebauten tun:Oder mit
declare
:quelle
bash
,typeset
ist veraltet und sein Ersatz istdeclare
. Sie sind mehr oder weniger identisch.typeset
ist ein bisschen portabler (funktioniert in ksh)Nach der Indirektion beim Abrufen des Werts einer Variablen …
Der tragbare Weg ist zu verwenden
eval
. Sie müssen auf das Anführungszeichen achten, damit Sonderzeichen im Wert nicht ausgewertet werden, wenn dies nicht der Fall sein sollte. Am einfachsten ist es, den neuen Wert in einer Zwischenvariablen zu speichern und den Wert dieser Variablen zuzuweisen.Das Argument dafür
eval
istB=$tmp
eine einfache Zuordnung. Sie benötigen keine doppelten Anführungszeichen,$tmp
auch wenn es Leerzeichen oder Globbing-Zeichen enthält, da diese in einer Zuweisung nicht erweitert werden.Wenn Sie eine Umgebungsvariable erstellen möchten, können Sie verwenden
export
. In bash oder ksh oder zsh können Sietypeset
eine lokale Variable erstellen (diesdeclare
gilt auch für bash). Auch hier sollten Sie eine Zwischenvariable verwenden, damit Sonderzeichen nicht entstellt werden. Beachten Sie, dass Sie außer in zsh doppelte Anführungszeichen um die Variablenerweiterung setzen müssen, da dies keine Zuweisung ist, sondern eine integrierte Funktion, die ein Argument verwendet, das zufällig wie eine Zuweisung aussieht.quelle
eval
ist die richtige Antwort. Es ist portabel, entspricht dem POSIX-Standard und wird überall in fortgeschritteneren Shell-Skripten verwendet. Eines jedoch: Die Verwendungexport
in derselben Zeile wie die Zuweisung ist nicht portierbar.export var=value
ist POSIX. Es ist nicht für Bourne-Shells tragbar, aber es handelt sich um eine verschwindende Rasse (verwenden Sie nur/usr/xpg4/bin/sh
oder/usr/xpg6/bin/sh
oder ksh und nicht/bin/sh
auf älteren Solaris-Computern).