Das Problem, überarbeitet
Ehrlich gesagt ist das Handbuch in diesem Punkt verwirrend. Das GNU Bash Handbuch sagt:
Die Umgebung für einfache Befehle oder Funktionen [beachten Sie, dass dies integrierte Funktionen ausschließt] kann vorübergehend erweitert werden, indem Parameterzuweisungen vorangestellt werden, wie unter Shell-Parameter beschrieben. Diese Zuweisungsanweisungen wirken sich nur auf die Umgebung aus, die von diesem Befehl angezeigt wird.
Wenn Sie den Satz wirklich analysieren, heißt es, dass die Umgebung für den Befehl / die Funktion geändert wird, nicht jedoch die Umgebung für den übergeordneten Prozess. Das wird also funktionieren:
$ TESTVAR=bbb env | fgrep TESTVAR
TESTVAR=bbb
weil die Umgebung für den Befehl env vor seiner Ausführung geändert wurde. Dies wird jedoch nicht funktionieren:
$ set -x; TESTVAR=bbb echo aaa $TESTVAR ccc
+ TESTVAR=bbb
+ echo aaa ccc
aaa ccc
aufgrund dessen, wann die Parametererweiterung von der Shell durchgeführt wird.
Dolmetscherschritte
Ein weiterer Teil des Problems besteht darin, dass Bash diese Schritte für seinen Interpreter definiert:
- Liest seine Eingabe aus einer Datei (siehe Shell-Skripte), aus einer als Argument angegebenen Zeichenfolge für die Aufrufoption -c (siehe Aufrufen von Bash) oder vom Terminal des Benutzers.
- Unterbricht die Eingabe in Wörter und Operatoren und befolgt dabei die in Quoting beschriebenen Anführungsregeln. Diese Token sind durch Metazeichen getrennt. Die Alias-Erweiterung wird durch diesen Schritt ausgeführt (siehe Aliase).
- Analysiert die Token in einfache und zusammengesetzte Befehle (siehe Shell-Befehle).
- Führt die verschiedenen Shell-Erweiterungen aus (siehe Shell-Erweiterungen) und unterteilt die erweiterten Token in Listen mit Dateinamen (siehe Dateinamenerweiterung) sowie Befehle und Argumente.
- Führt alle erforderlichen Umleitungen durch (siehe Umleitungen) und entfernt die Umleitungsoperatoren und ihre Operanden aus der Argumentliste.
- Führt den Befehl aus (siehe Ausführen von Befehlen).
- Wartet optional auf den Abschluss des Befehls und sammelt seinen Exit-Status (siehe Exit-Status).
Was hier passiert, ist, dass Buildins keine eigene Ausführungsumgebung erhalten, sodass sie die geänderte Umgebung nie sehen. Darüber hinaus einfache Befehle (zB / bin / echo) Sie erhalten eine modifizierte ennvironment (weshalb das env Beispiel arbeitete) , aber die Shell - Erweiterung ist in der stattfindet aktuellen Umgebung in Schritt # 4.
Mit anderen Worten, Sie übergeben 'aaa $ TESTVAR ccc' nicht an / bin / echo; Sie übergeben die interpolierte Zeichenfolge (wie in der aktuellen Umgebung erweitert) an / bin / echo. In diesem Fall übergeben Sie einfach 'aaa ccc' an den Befehl , da die aktuelle Umgebung kein TESTVAR enthält .
Zusammenfassung
Die Dokumentation könnte viel klarer sein. Gut, dass es einen Stapelüberlauf gibt!
Siehe auch
http://www.gnu.org/software/bash/manual/bashref.html#Command-Execution-Environment