${!FOO}
Führt eine Doppelsubstitution in durch bash
, dh, es wird der (Zeichenfolge-) Wert von FOO als Variablenname verwendet.
zsh
unterstützt diese Funktion nicht.
Gibt es eine Möglichkeit, diese Arbeit in bash
und gleich zu machen zsh
?
Hintergrund:
Ich habe eine Liste von Umgebungsvariablen, wie
PATH MAIL EDITOR
und wollen zuerst die Variablennamen und danach ihre Werte drucken.
Das funktioniert in bash
aber nicht zsh
:
for VAR in LIST
do
echo $VAR
echo ${!VAR}
done
Es sollte irgendwie "auf die alte Art" möglich sein eval
, aber ich kann es nicht zum Laufen bringen:
for VAR in LIST
do
echo $VAR
echo `eval \$$VAR`
done
Ich werde nie verstehen, warum ich nicht einfach willkürliche tiefe Substitutionen wie ${${VAR}}
oder sogar ${${${VAR}}}
wenn nötig durchführen kann, daher wäre auch eine Erklärung dafür nett.
bash
zsh
variable-substitution
for
Profpatsch
quelle
quelle
bash
, es hat in der Tat die gleiche Funktion (und vieles mehr), es wird nur ein anderes Muster verwendet, nämlich${(p)FOO}
.(e)
Parametererweiterungsflag von zsh wurde in zsh-2.6-beta17 (Mai 1996) hinzugefügt, das(P)
Flag in 3.1.5-pws-7 (1999). Bash${!var}
in 2.0 (Dezember 1996).Antworten:
Sowohl bash als auch zsh können indirekt expandieren, verwenden jedoch eine andere Syntax.
Es ist einfach genug, eine indirekte Erweiterung mit durchzuführen
eval
. Dies funktioniert in allen POSIX- und den meisten Bourne-Shells. Achten Sie auf korrekte Anführungszeichen, falls der Wert Zeichen enthält, die in der Shell eine besondere Bedeutung haben.${${VAR}}
funktioniert nicht, weil es keine Funktion ist, die von einer Shell implementiert wird. Das in geschweiften Klammern stehende Element muss Syntaxregeln entsprechen, die keine enthalten${VAR}
. (In zsh wird diese Syntax unterstützt, sie führt jedoch etwas anderes aus: Verschachtelte Ersetzungen führen aufeinanderfolgende Transformationen für denselben Wert durch;${${VAR}}
entspricht,$VAR
da hierdurch die Identitätsumwandlung für den Wert zweimal ausgeführt wird.)quelle
Der Kommentar unter der ursprünglichen Frage von Profpatsch gibt das Beispiel
${(p)FOO}
für die Ausgabe des Inhalts einer indirekten Variablenreferenz. Das Flag ist falsch oder ein Tippfehler. Es sollte ein P in Großbuchstaben und kein p in Kleinbuchstaben sein. Verwendung:${(P)FOO}
.Folgendes sollte die gewünschte Ausgabe erzeugen:
Aus der Manpage zshexpn ; section - Parameter-Erweiterungsflags :
Einmal las ich, warum
${${${VAR}}}
nicht die erwartete Ausgabe erzeugt wird, aber zu diesem Zeitpunkt kann ich es nicht finden. Sie können Folgendes tun:quelle
Sie verwenden eval nicht richtig. In Ihrem Beispiel würde der Wert von $ VAR, dem ein "$" (dh "$ VALUE") vorangestellt ist, als Befehl ausgeführt. Das ist nicht was du willst. Sie möchten die Erweiterung einer Variablen auswerten, deren Name einer anderen Variablen entnommen ist.
quelle
{ba,z}sh
LösungHier ist eine Funktion, die sowohl in {ba, z} sh funktioniert. Ich glaube, es ist auch POSIX-konform.
Es warnt, wenn gegeben:
quelle
function
noch[[...]]
in POSIXsh
.[ "$#" -eq 0 ]
(oder wahrscheinlich,[ "$#" -ne 1 ]
da Sie nur ein Argument erwarten).shell-check
könnte auch helfen.${1-}
angegeben wirda='"" -o -n 1'
[ -z $a ]
==0
. Aber wird es nicht$#
immer ein einziges Zeichen sein?