Der Shellshock- Fehler in Bash funktioniert über Umgebungsvariablen. Ehrlich gesagt war ich überrascht von der Tatsache, dass es so ein Feature gibt wie:
"Weitergabe von Funktionsdefinitionen über env vars"
Daher ist diese Frage, obwohl sie möglicherweise nicht perfekt formuliert ist, die Frage nach einem Beispiel oder einem Fall, in dem diese Funktion erforderlich wäre.
Bonus. Haben auch andere Shells zsh, dash etc. diese Funktion?
bash
environment-variables
function
shellshock
Menschlichkeit UND Frieden
quelle
quelle
parallel
Weise Funktionsdefinitionen verteilt, wenn mehrere Bash-Instanzen aufgerufen werden. Wenn dies nicht der Fall wäre, müssten diese in eine Datei geschrieben werden, die von jeder aufgerufenen Instanz eingelesen wird, und dann müssen Sie sich mit Problemen befassen, z. B. wann diese Datei entfernt werden kann..dot
dieselbe Datei wie die alte Shell. So wird es gemacht - und das macht Sinn - oder Sie geben der neuen Shell die Datei als Eingabe beimexec
Ing. Sobald es eingelesen ist, wird die Datei ohnehin vom Kernel zwischengespeichert.Antworten:
Wenn ein Skript ein anderes Skript aufruft, können Variablen des übergeordneten Skripts exportiert werden, die dann im untergeordneten Skript angezeigt werden. Das Exportieren von Funktionen ist eine offensichtliche Verallgemeinerung: Exportieren Sie die Funktion vom übergeordneten Element und machen Sie sie im untergeordneten Element sichtbar.
Die Umgebung ist die einzig bequeme Möglichkeit, wie ein Prozess beliebige Daten an seine untergeordneten Elemente weitergeben kann. Die Daten müssen in Zeichenfolgen zusammengefasst werden, die keine Null-Bytes enthalten, was für Shell-Funktionen keine Schwierigkeit darstellt. Es gibt andere mögliche Methoden, wie z. B. gemeinsam genutzte Speicherblöcke oder temporäre Dateien, die über Dateideskriptoren übergeben werden. Diese können jedoch Probleme mit Zwischenprogrammen verursachen, die nicht wissen, was sie damit tun sollen, oder sie schließen würden. Programme werden voraussichtlich in einer Umgebung ausgeführt, die Variablen enthält, die sie nicht kennen oder für die sie sich nicht interessieren, damit sie nicht überschrieben oder gelöscht werden.
Die Wahl, den Funktionsnamen als Namen der Umgebungsvariablen zu verwenden, ist seltsam. Zum einen bedeutet dies, dass eine exportierte Variable mit einer exportierten Funktion mit demselben Namen kollidiert.
Exportierte Funktionen sind eine alte Funktion. In der Bourne-Shell in SVR2 wurden Funktionen hinzugefügt und Funktionen in der Version 8-Shell exportiert, die im selben Jahr (1984) veröffentlicht wurde. In dieser Shell verwendeten Variablen und Funktionen denselben Namespace. Ich weiß nicht, wie der Funktionsexport funktioniert hat. Die Heirloom-Shell basiert auf einer Bourne-Variante, die Funktionen hat, diese aber nicht exportiert.
ATT ksh unterstützt angeblich das Exportieren von Funktionen, aber wenn ich mir die Quelle anschaue oder damit spiele, kann ich nicht sehen, dass dies ab ksh93u der Fall ist.
Die Public Domain-Klone (pdksh, mksh), dash und zsh von Ksh unterstützen keine Exportfunktionen.
quelle
BASH_FUNC_f%%=() { echo hi }
. Warum sollte bash andere Umgebungsvariablen analysieren? Warum sollte es überhaupt analysiert werden,BASH_FUNC_g%%
wenn ich nur anrufef
? (Anscheinend, vor dem Shellshock, wurde die Umgebungsvariable gerade aufgerufenf
oderg
- aber ich frage mich immer noch, warumg
sie analysiert worden wäre, wenn ichg
mein Skript nie aufgerufen hätte)f
, (1) nach einer aufgerufenen Shell-Funktion zu suchenf
, (2) nach einer aufgerufenen Umgebungsvariablen zuf
suchen und zu versuchen, sie zu analysieren, (3) zu prüfen JedePATH
Komponente für eine ausführbare Datei wird aufgerufenf
. Wie könnte das Parsen jeder Umgebungsvariablen als Shell-Code beim Shell-Start als weniger kompliziertes Design erscheinen?unset -f foo
muss bash nicht mehr nach einer Funktionsdefinitionfoo
in der Umgebung suchen ), wenn Sie Funktionen auflisten (wie gehen Siedeclare -f
anders vor, als alle Umgebungsvariablen zu lesen?) und an was auch immer ich sonst nicht denke. Ihr Design scheint nur einfacher zu sein, weil Sie das meiste davon weggelassen haben. Im Gegensatz dazu ist alles beim Start ein einziger Code, und danach funktioniert einfach alles.