Ich kann dies tun, aber es erfordert, dass eine Zeichenfolge der Variablen erstellt und dann dereferenziert wird. Gibt es eine Möglichkeit, es auf eine einfachere Aussage zu verkürzen?
#!/bin/bash
FRUITS="BANANA APPLE ORANGE"
BANANA_COLOUR="Yellow"
APPLE_COLOUR="Green or Red"
ORANGE_COLOUR="Blue"
for fruit in $( echo $FRUITS ); do
fruit_colour="${fruit}_COLOUR"
echo $fruit is ${!fruit_colour}
done
Ich habe viele Dinge wie ${!"${fruit}_COLOUR"}
oder \$${fruit}_COLOUR
und viele andere Varianten ausprobiert , aber der einzige Weg, der funktioniert hat, ist die Verwendung eines Strings.
bash
variable-substitution
Matte
quelle
quelle
!
Syntax ist ein Flag für die Variablensubstitution, das im Grunde "zweimal ersetzen" sagt. Es ändert nichts an der Anforderung, dass das, was sich im${…}
befindet, ein Variablenname sein muss. Nein, Sie können es nicht vermeiden, eine Variable zu verwenden, die den Namen enthält, es sei denn, Sie verwenden eine andere Methode (eval
).Antworten:
Zunächst müssen Sie nicht
$(echo $FRUITS)
in derfor
Anweisung verwenden. Nur zu benutzen$FRUITS
ist genug. Dann können Sie mit eine der Linien in der Schleife entferneneval
.Das
eval
fordert bash einfach auf, eine zweite Bewertung der folgenden Aussage vorzunehmen (dh eine mehr als die normale Bewertung). Der\$
überlebt die erste Auswertung als$
, und die nächste Auswertung behandelt dies dann$
als den Beginn eines Variablennamens, der in "Gelb" usw. aufgelöst wird.Auf diese Weise brauchen Sie keinen separaten Schritt, der eine Zwischenzeichenfolge erstellt (was meiner Meinung nach die Hauptabsicht Ihrer Frage war).
Für eine alternative Methode, wie von Patrick in einem Kommentar (oben) erwähnt, können Sie stattdessen ein assoziatives Array verwenden , in dem der Index eines Elements keine Ganzzahl sein muss. Sie können eine Zeichenfolge verwenden, z. B. den Namen einer Obstsorte. Hier ist ein Beispiel mit dem assoziativen Array von bash:
quelle
Sie können die Bash-Builtin verwenden,
eval
um dies zu tun:Beachten Sie das umgekehrte Dollarzeichen. Grundsätzlich wird durch die "eval" -Linie
bash
ersetzt$fruit
und${fruit_color}
anschließendeval
eine zweite Runde der Substitution durchgeführt, bevor der Anruf ausgeführt wirdecho
.quelle
Sie brauchen keine Bewertung.
eval
ist in den meisten Sprachen ein Hinweis darauf, dass Sie etwas falsch machen.quelle
eval
da zumindest die Leute wissen, dass es gefährlich${!var}
ist, ungefähr genauso gefährlich istbash
(auch eine Sicherheitsanfälligkeit durch Befehlsinjektion, wenn$chosen_prefix
es unter der Kontrolle eines Angreifers steht) und weniger Menschen davon Kenntnis haben. Versuchen Sie esvar_name='a[$(uname>&2)0]' bash -c 'v=${!var_name}'
. Der beste Ansatz ist hier das assoziative Array.