Umgebungsvariablen, die Funktionen enthalten, sind ein Bash-Hack. Zsh hat nichts ähnliches. Mit ein paar Codezeilen können Sie etwas Ähnliches tun. Umgebungsvariablen enthalten Zeichenfolgen. Ältere Versionen von bash haben vor der Entdeckung von Shellshock den Funktionscode in einer Variablen gespeichert, deren Name der der Funktion entspricht und auf deren Wert () {
der Funktionscode folgt }
. Mit dem folgenden Code können Sie Variablen mit dieser Codierung importieren und versuchen, sie mit bashartigen Einstellungen auszuführen. Beachten Sie, dass zsh nicht alle Bash-Funktionen emulieren kann. Sie können jedoch ein wenig näher heranrücken (z. B. um $foo
den Wert zu teilen und Platzhalter zu erweitern und Arrays auf der Basis von 0 zu erstellen).
bash_function_preamble='
emulate -LR ksh
'
for name in ${(k)parameters}; do
[[ "-$parameters[name]-" = *-export-* ]] || continue
[[ ${(P)name} = '() {'*'}' ]] || continue
((! $+builtins[$name])) || continue
functions[$name]=$bash_function_preamble${${${(P)name}#"() {"}%"}"}
done
(Wie Stéphane Chazelas , der ursprüngliche Entdecker von Shellshock, feststellte, könnte eine frühere Version dieser Antwort an dieser Stelle beliebigen Code ausführen, wenn die Funktionsdefinition fehlerhaft ist. Dies gilt jedoch nicht, sobald Sie einen Befehl ausführen.) Es könnte sich um eine aus der Umgebung importierte Funktion handeln.)
Post-Shellshock-Versionen von bash codieren Funktionen in der Umgebung mit ungültigen Variablennamen (z BASH_FUNC_myfunc%%
. B. ). Dies macht es schwieriger, sie zuverlässig zu analysieren, da zsh keine Schnittstelle zum Extrahieren solcher Variablennamen aus der Umgebung bietet.
Ich empfehle das nicht. Es ist eine schlechte Idee, sich auf exportierte Funktionen in Skripten zu verlassen: Sie erzeugen eine unsichtbare Abhängigkeit in Ihrem Skript. Wenn Sie Ihr Skript jemals in einer Umgebung ausführen, die nicht über Ihre Funktion verfügt (auf einem anderen Computer, in einem Cron-Job, nachdem Sie Ihre Shell-Initialisierungsdateien geändert haben, ...), funktioniert Ihr Skript nicht mehr. Speichern Sie stattdessen alle Ihre Funktionen in einer oder mehreren separaten Dateien (etwa ~/lib/shell/foo.sh
) und starten Sie Ihre Skripte, indem Sie die verwendeten Funktionen importieren ( . ~/lib/shell/foo.sh
). Wenn Sie Änderungen vornehmen foo.sh
, können Sie auf diese Weise leicht nach den Skripten suchen, die darauf angewiesen sind. Wenn Sie ein Skript kopieren, können Sie leicht herausfinden, welche Zusatzdateien es benötigt.
Zsh (und ksh davor) erleichtert dies, indem Funktionen in Skripten, in denen sie verwendet werden, automatisch geladen werden. Die Einschränkung ist, dass Sie nur eine Funktion pro Datei einfügen können. Deklarieren Sie die Funktion als automatisch geladen und fügen Sie die Funktionsdefinition in eine Datei ein, deren Name der Name der Funktion ist. Legen Sie diese Datei in einem Verzeichnis ab $fpath
(das Sie über die FPATH
Umgebungsvariable konfigurieren können ). Deklarieren Sie in Ihrem Skript automatisch geladene Funktionen mit autoload -U foo
.
Außerdem kann zsh Skripte kompilieren, um Parsing-Zeit zu sparen. Rufen Sie zcompile
auf, um ein Skript zu kompilieren. Dadurch wird eine Datei mit der .zwc
Erweiterung erstellt. Wenn diese Datei vorhanden ist, autoload
wird die kompilierte Datei anstelle des Quellcodes geladen. Mit der zrecompile
Funktion können Sie alle Funktionsdefinitionen in einem Verzeichnis (neu) kompilieren.