Normalerweise ist es möglich, eine Umgebungsvariable für einen Befehl festzulegen, indem Sie ihn wie folgt voranstellen:
hello=hi bash -c 'echo $hello'
Ich weiß auch, dass wir eine Variable verwenden können, um einen beliebigen Teil eines Befehlsaufrufs wie folgt zu ersetzen:
$ cmd=bash
$ $cmd -c "echo hi" # equivalent to bash -c "echo hi"
Ich war sehr überrascht, als ich herausfand, dass Sie einem Befehl zum Festlegen einer Umgebungsvariablen keine Variable voranstellen können. Testfall:
$ prefix=hello=hi
$ echo $prefix # prints hello=hi
$ $prefix bash -c 'echo $hello'
hello=hi: command not found
Warum kann ich die Umgebungsvariable nicht mithilfe einer Variablen festlegen? Ist der Präfixteil ein besonderer Teil? Ich konnte es mit eval front zum Laufen bringen, aber ich verstehe immer noch nicht warum. Ich benutze Bash 4.4.
bash
environment-variables
variable
wbkang
quelle
quelle
env
stattdessen verwendeneval
, welches IIRC sicherer, aber langsamer ist.Antworten:
Ich vermute, das ist der Teil der Sequenz, der dich fängt:
Dies stammt aus dem Bash-Referenzhandbuch im Abschnitt über die einfache Befehlserweiterung.
In diesem
cmd=bash
Beispiel werden keine Umgebungsvariablen festgelegt, und bash verarbeitet die Befehlszeile durch Parametererweiterungbash -c "echo hi"
.In diesem
prefix=hello=hi
Beispiel gibt es im ersten Durchgang wieder keine Variablenzuweisungen, sodass die Verarbeitung mit der Parametererweiterung fortgesetzt wird, was zu einem ersten Wort von führthello=hi
.Sobald die Variablenzuweisungen verarbeitet wurden, werden sie während der Befehlsausführung nicht erneut verarbeitet.
Siehe die Verarbeitung und ihre Ergebnisse unter
set -x
:eval
Betrachten Sieenv
für eine sicherere Variante der "Variablenerweiterung" als "Umgebungsvariablen" den Vorschlag von wjandrea :Es handelt sich nicht ausschließlich um eine Zuweisung von Befehlszeilenvariablen, da wir die
env
Hauptfunktion des Dienstprogramms zum Zuweisen von Umgebungsvariablen zu einem Befehl verwenden, aber das gleiche Ziel erreicht. Die$prefix
Variable wird während der Verarbeitung der Befehlszeile erweitert und gibt den Namen = Wert anenv
, an den sie weitergegeben wirdbash
.quelle
$foo=bar bash -c ...
funktioniert es nicht, da$foo=bar
es sich nicht um eine Variablenzuweisung handelt (unabhängig vom Wert von$foo
), da$foo=bar
es nicht zumname=value
Muster für die Variablenzuweisung passt .Weil
$prefix
es keine Aufgabe ist. @ Jeff hat die längere Erklärung .Sie könnten stattdessen etwas Ähnliches mit einer Funktion tun:
... und Sie können diese sogar stapeln, wenn Sie möchten:
quelle