HomeSoftwareSpieleMusikForum

Shellfunktionen laden

Autoload ksh: Die Kornshell verfügt zudem über einen Autoload-Mechanismus. Um ihn benutzen zu können, muss man zusätzlich zu den oben erwähnten Vorbereitungen die Variable FPATH mit einer Liste der Funktionsverzeichnisse besetzen. $FPATH ist also eine Untermenge von $PATH. Wenn diese Bedingungen erfüllt sind, sucht ksh jede aufgerufene Funktion, die noch nicht definiert ist, über $FPATH und lädt sie automatisch. Ein explizites source ist nicht erforderlich.

Das ist bequem, allerdings kann das Verfahren auch Nachteile haben. Ruft man nämlich eine Funktion func in einem Script nur in der Form $(func parameter...) auf, also nur in Subshells, wird sie bei jedem Aufruf gesucht und geladen, was ziemlich ineffektiv ist. [1] In diesem Fall empfiehlt es sich, die Funktion am Beginn des Scripts explizit mit source func zu laden; danach wird die Definition automatisch an Subshells weitergegeben. Achtung: Diese Anweisung darf wirklich nur einmal gegeben werden. Ist func bereits definiert, bewirkt source func einen Aufruf, nicht eine Neudefinition. Um sicher zu gehen, kann man statt des Namens den absoluten Pfad der Definitionsdatei angeben oder eine Bedingung vorschalten:

typeset +f func >/dev/null || source func

Autoload bash: Die Bash hat keinen eingebauten Autoload-Mechanismus. Im Quellpaket finden sich jedoch im Verzeichnis examples/functions verschiedene Varianten einer Funktion autoload, mit denen der ksh-Mechanismus weitgehend nachgebildet werden soll. Das Prinzip besteht darin, anstelle der eigentlichen (möglicherweise sehr großen) Funktion eine kleine Platzhalter-Funktion mit gleichem Namen zu definieren. Wird diese aufgerufen, überschreibt sie zunächst sich selbst mit der eigentlichen Funktion und ruft diese dann mit der ihr übergebenen Parameterliste auf.

Nachstehend meine eigene, auf das Wesentliche reduzierte Variante.

Ich lade sie in /etc/profile und führe danach den Aufruf
autoload $(ls $AUTOLOAD)
durch; die Variable AUTOLOAD enthält das Verzeichnis, in dem alle automatisch zu ladenden Funktionen liegen.

Zu meiner Version noch einige Anmerkungen:

  • autoload prüft nicht, ob die gewünschte Funktion bereits geladen ist. Beim 2. Aufruf wird daher für f wieder die Platzhalterfunktion geladen. Man kann das benutzen, um die End-Funktion f zwischen zwei Aufrufen aus dem Speicher zu entfernen.
  • Falls für die zu ladende Funktion spezielle Vervollständigungen (completions) existieren, sollten diese bereits beim ersten Aufruf, d.h. bei der Platzhalterfunktion wirksam sein. Mein autoload sucht deshalb in einem speziellen Verzeichnis (Variable COMPLETIONS) nach einer Datei gleichen Namens; falls sie existiert, wird sie mit source ausgeführt.
  • Das Kommando unset-f "name" scheint eigentlich überflüssig zu sein, da die Funktion gleich danach neu definiert wird. Nach meinen Erfahrungen kann das Fehlen dieses Kommandos jedoch zumindest in bash 4.1 zu anhaltend krankhaftem Verhalten führen.


[1] Ab Version ksh93t gibt es eine effizientere Kommandoersetzung ${ kommando;}, die in der aktuellen Shell durchgeführt wird.

up
Created 2011-08-11 by mopcoge