Also fing ich an zu benutzen zsh
. Mir gefällt es gut. Es scheint sehr cool und flott zu sein, und die Tatsache, dass das aktuelle Arbeitsverzeichnis und die aktuelle Befehlszeile in verschiedenen Zeilen stehen, ist schön, aber gleichzeitig fällt mir auf, dass zsh
dies etwas langsamer sein kann als bash
, insbesondere beim Drucken von Text auf Bildschirm.
Das, was mir am besten gefallen hat, war die Tatsache, dass zsh
es mit allen Funktionen, die ich in meinem definiert habe , "abwärtskompatibel" war .bashrc
.
Ein Kritikpunkt. Die Funktionen funktionieren alle perfekt, aber ich kann nicht herausfinden, wie das Exportsystem funktioniert.
Ich habe einige dieser .bashrc
Funktionen exportieren lassen, damit ich sie an anderer Stelle verwenden kann, z. B. in Skripten und externen Programmen mit export -f
.
In zsh scheint nicht einmal über den Export gesprochen zu werden. Wird automatisch geladen? Sind diese beiden Dinge gleich? Es fällt mir schwer, das herauszufinden.
quelle
Antworten:
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).(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 vornehmenfoo.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 dieFPATH
Umgebungsvariable konfigurieren können ). Deklarieren Sie in Ihrem Skript automatisch geladene Funktionen mitautoload -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 derzrecompile
Funktion können Sie alle Funktionsdefinitionen in einem Verzeichnis (neu) kompilieren.quelle
bash
(überprüft nicht, ob der Inhalt der Variablen nur eine Funktionsdefinition ist und verarbeitet einen Variablennamen wieHTTP_HOST
oderLC_X
). Gute Antwort ansonsten.zsh -c 'functions[f]=$VAR'
wird analysiert , auch wenn dief
Funktion aufgerufen wird nie). Die Lösung besteht darin, nur Variablen zu berücksichtigen, deren Name einer reservierten Vorlage folgt$BASH_FUNC_x%%
, die jedoch, wie Sie sagen,zsh
keine API zum Auflisten oder Abrufen dieser enthält. Sie müssten zum Beispiel anrufenperl
.Wenn Sie Ihre Funktionsdeklaration in .zshenv einfügen , kann Ihre Funktion mühelos aus einem Skript verwendet werden.
quelle
.zshenv
und verlangsamen Sie jeden Aufruf von zsh, indem Sie eine Menge Code analysieren, der nie benutzt wird. Außerdem ist es nicht dasselbe wie das Exportieren einer Funktion, genau wie eine exportierte Variable, eine exportierte Funktion ist nur für untergeordnete Prozesse verfügbar. Während die Sachen, die Sie in setzen,.zshenv
zu jedem zsh verfügbar sind..zshenv
, sind alle Ihre Skripte nicht portierbar. Normalerweise könnten Skripte voneinander abhängen, was in Ordnung ist, Sie verteilen sie zusammen. Wenn sie jedoch von speziellen Funktionen abhängen.zshenv
, wird niemand sie verwenden wollen oder sie müssten mit einem speziellen aufgerufen werdenZDOTDIR
, um zu verhindern, dass Ihre eigenen Funktionen.zshenv
ausgeführt werden. Es wäre ein Schmerz.