![]() |
|
||||||||||||||||||||
|
|||||||||||||||||||||
|
|||||||||||||||||||||
von Elisabeth Bauer
Wer manchmal mit der Linux-Kommandozeile arbeite, kennt das Problem: Viele Befehle sind so schwer zu merken und haben derart viele Aufrufparameter, dass man immer erst in die Manpage des Kommandos schauen muss, um eine einfache Aufgabe zu erledigen. Ein weiteres Ärgernis ist die Tipparbeit. Gerade Befehle mit vielen Parametern kosten bei der Eingabe viel Zeit. Um sich die Arbeit zu erleichtern, besteht die Möglichkeit, Shell-Funktionen zu verwenden. Wer häufig immer dieselben Kommandos eintippt, spart sich damit eine Menge Arbeit. Mit einem Aufruf führt die Shell dann gleich eine ganze Reihe von Befehlen aus, ohne dass Sie sie einzeln eingeben müssen.
Der Aufbau einer Funktion schaut so aus:
funktionsname() {
ein_Befehl
noch_einer
}
Am Anfang steht der Name, mit dem Sie die Funktion später aufrufen, gefolgt von runden Klammern. Die erste geschweifte Klammer ist das Signal für die Shell, dass nun alle Befehle folgen, die die Funktion zusammenfassen soll. Diese Kommandos schreiben Sie jeweils in eine Zeile. Sie sind dabei nicht auf zwei wie im obigen Beispiel beschränkt, sondern können Ihre Funktion beliebig viele Befehle abarbeiten lassen. Am besten veranschaulicht ein praktisches Beispiel, wie eine solche Shell-Funktion arbeitet.
Ihre Heimat haben Funktionen in der Datei .bashrc, die unter Linux versteckt im Home-Verzeichnis eines Benutzers liegt. Diese Datei können Sie mit jedem beliebigen Text-Editor bearbeiten und an Ihre Bedürfnisse anpassen. Hier verwenden wir als Beispiel den KDE-Text-Editor KWrite, da dieser im Gegensatz zu den Shell-Klassikern vi und emacs als grafisches Programm auch für Anfänger leicht zu bedienen ist.
Eine erste einfache Beispielfunktion erstellen Sie im Handumdrehen: Starten Sie aus einem Terminal-Fenster den Text-Editor KWrite und weisen Sie ihn an, die Datei .bashrc zu öffnen:
kwrite ~/.bashrc &
Die Tilde ist dabei eine Abkürzung, die die Shell automatisch durch den Pfad zu Ihrem Home-Verzeichnis ersetzt, also etwa durch /home/eli. Das & am Ende der Befehlszeile sorgt dafür, dass die Shell Ihnen nach dem Start von KWrite wieder einen so genannten Prompt zurückgibt, so dass Sie weitere Befehle eingeben können. Wenn Sie das Zeichen weglassen, ist die Shell solange blockiert, bis Sie kwrite beenden. Möchten Sie die .bashrc aus einem schon gestarteten KWrite heraus über den Dateidialog öffnen, drücken Sie im Auswahlfenster [F8]. Daraufhin zeigt der Text-Editor auch die versteckten, mit einem Punkt beginnenden Konfigurationsdateien in der Liste an (Abbildung 1).
Bei einigen Distributionen stehen in der .bashrc schon verschiedene Befehle. Diese können Sie getrost ignorieren und wie in Abbildung 2 Ihre erste Funktion darunter setzen:
mein-test() {
echo "Hallo, dein aktuelles Verzeichnis ist"
pwd
echo "und dort liegen:"
ls
}
Speichern Sie die Datei und wechseln Sie zurück ins Terminal. Die Shell weiß noch nichts von der Änderung, deshalb weisen Sie sie mit
. ~/.bashrc
an, die Datei neu zu lesen. Der Punkt ist eine Abkürzung für das Kommando source, das Sie in manchen Handbüchern finden. Beim nächsten Login oder wenn Sie eine neue Shell aufmachen, ist dieser Aufruf nicht mehr nötig. Mit
mein-test
rufen Sie die neue Funktion auf. Die Shell führt nun die vier Kommandos aus, die zwischen den geschweiften Klammern stehen: echo gibt den Text in Anführungszeichen, pwd (print working directory) das aktuelle Verzeichnis und ls eine Liste der darin enthaltenen Dateien und Ordner aus (Abbildung 3).
Auf diese Art fassen Sie beliebige Kommandos zusammen. Ein praktischer Anwendungsfall ist zum Beispiel das Starten mehrerer Programme in einem Rutsch. Wer die KDE-Sitzungsverwaltung nutzt, hat sich bestimmt schon einmal darüber geärgert: Wenn Sie KDE beenden, speichert die Desktop-Umgebung, welche Anwendungen gerade laufen, und startet sie beim nächsten Anmelden erneut. Dieses Verhalten ist jedoch lästig, wenn Sie sich nur anmelden, um schnell etwas am Rechner zu erledigen und dann warten müssen, bis die Sitzungsverwaltung das Starten der Anwendungen beendet hat.
Haben Sie deshalb die Sitzungsverwaltung im KDE-Kontrollzentrum unter KDE-Komponenten / Sitzungsverwaltung deaktiviert (Abbildung 4), können Sie ersatzweise eine Shell-Funktion nutzen, die alle benötigten Anwendungen mit nur einem einzigen Befehl startet. Die folgende Funktion ruft zum Beispiel die Programme KMail, Gimp und den MP3-Player XMMS auf:
start() {
kmail &
gimp &
xmms &
}
Speichern Sie die .bashrc, lesen Sie sie mit . ~/.bashrc im Konsolen-Fenster neu ein und rufen Sie die neue Funktion mit der Eingabe von start auf. Daraufhin arbeitet die Shell alle Befehle zwischen den geschweiften Klammern ab, startet also die drei dort eingestellten Programme.
Zusätzlichen Komfort erhalten Sie, indem Sie die Funktion ein wenig modifizieren:
start() {
pushd
kmail &
cd $HOME/bilder
gimp &
cd $HOME/musik
xmms &
popd
}
Das Kommando pushd merkt sich das Verzeichnis, in dem Sie sich gerade befinden. popd am Ende der Funktion ist das passende Gegenstück und springt wieder in den mit pushd gespeicherten Ordner zurück. Vor dem Start von Gimp wechselt die Shell in das Verzeichnis bilder (cd $HOME/bilder) in Ihrem Home-Verzeichnis und anschließend nach musik (cd $HOME/musik). Wenn Sie nun in Gimp oder XMMS eine Datei öffnen, bietet der Auswahldialog Ihnen sofort das passende Verzeichnis bilder bzw. musik an. In den beiden Kommandos zum Verzeichniswechsel steht $HOME für das Home-Verzeichnis Ihres Benutzers. Bei $HOME handelt es sich um eine so genannte Variable, was Sie an dem vorangestellten Dollarzeichen erkennen.
Mit diesem Wissen sparen Sie eine Menge Tipparbeit ein. Denkbar sind zum Beispiel Startfunktionen für Programmgruppen, die Sie häufig zur gleichen Zeit verwenden: Eine Funktion start_net, die Browser, E-Mail- und Chat-Client startet, und eine Funktion start_work, die Textverarbeitung, Tabellenkalkulation und weitere Anwendungen für eher unangenehme Routineaufgaben zusammenfasst.
Wichtig beim Shell-Programmieren -- nichts anderes machen Sie hier -- ist es, auf Kleinigkeiten zu achten. Wenn eine Funktion nicht das tut, was Sie erwarten oder nur eine Fehlermeldung ausgibt, schauen Sie sich die Zeilen noch einmal genau an: Sitzen alle Leerzeichen an der richtigen Stelle? Sind alle Befehle korrekt geschrieben? Geben Sie die Befehle normal in der Shell ein, um sie zu testen. Wenn Sie den Fehler partout nicht finden, hilft der Echo-Trick: Die Shell arbeitet die Befehle einer Funktion Zeile für Zeile ab. Stößt sie dabei auf einen Fehler, gibt sie meistens eine Fehlermeldung aus. Manchmal bleibt sie aber auch einfach hängen -- zum Beispiel, weil der Befehl weitere Eingaben erwartet -- und gibt gar nichts mehr aus. Um den Schuldigen zu identifizieren, setzen Sie nach jeden Befehl einen Aufruf von echo, in dem Sie angeben, welcher Befehl gerade ausgeführt wurde.
Im Beispiel der Funktion start würden Sie etwa
echo "kmail gestartet"
hinter den KMail-Aufruf setzen usw. und könnten genau verfolgen, welche Befehle die Shell schon ausgeführt hat und in welcher Zeile sie stolpert.
Bisher haben Sie nur Befehle verwendet, die keine zusätzlichen Angaben wie einen Verzeichnis- oder Dateinamen erwarten, oder Sie haben diese fest in die Funktion eingebaut, wie im Beispiel der Verzeichniswechsel mit cd. Die Möglichkeiten von Shell-Funktionen sind damit jedoch nicht ausgereizt: Das nächste Beispiel knöpft sich das Kommando tar vor [1]. tar packt Verzeichnisse und Dateien -- auf Wunsch komprimiert -- in eine Archivdatei und eignet sich so wunderbar dazu, Backups anzufertigen oder einen Stapel Dateien bequem zu verschicken. Die Aufrufparameter von tar sind leider weniger hübsch -- zum Aus- und Entpacken müssen Sie sich gleich vier Optionen merken:
tar czvf datei.tar.gz verzeichnis
packt verzeichnis in ein gzip-komprimiertes Archiv namens datei.tar.gz. c steht für create (Erzeugen), z sorgt für die Kompression mit gzip, v (verbose) weist tar an, alle Dateinamen auszugeben, und f bestimmt, dass tar ein Dateiarchiv anlegen soll, statt zum Beispiel die Daten auf ein Bandlaufwerk zu schreiben (wozu das Kommando früher hauptsächlich diente). Auch zum Auspacken sind Sie wieder mit vier Buchstaben dabei:
tar xzvf datei.tar.gz
entpackt das Archiv im aktuellen Verzeichnis. Mit der folgenden Funktion ersparen Sie sich die Tipparbeit beim Einpacken:
pack() {
tar czvf "$1-$(date +%y%m%d-%H%M%S).tar.gz" "$1"
}
Das sieht auf den ersten Blick reichlich kompliziert aus. Sie rufen die Funktion mit dem Verzeichnis auf, das Sie einpacken wollen, zum Beispiel:
pack photoalbum
In der Funktion finden Sie zweimal die Variable $1. Dort setzt die Shell automatisch das Argument ein, mit dem Sie die Funktion aufrufen. So führt sie in diesem Fall den Befehl
tar czvf "photoalbum-$(date +%y%m%d-%H%M%S).tar.gz" photoalbum
aus. Mit $(date +%y%m%d-%H%M%S) sorgen Sie dafür, dass das aktuelle Datum und die Uhrzeit Bestandteil des Archivnamens werden. Damit erhalten Sie auf bequeme Art ein Archiv mit Datumsstempel. Es erweist sich vor allem dann als praktisch, wenn Sie einen Ordner regelmäßig als Tar-Datei sichern.
Das Tar-Beispiel zeigt recht gut einen Hauptnutzen von Funktionen: Sie kürzen damit häufig gebrauchte Kommandos ab, bei denen Sie sich sonst schnell die Finger wundtippen oder deren Optionen Sie sich beim besten Willen nicht merken können. Gegenüber dem Befehl alias [2] haben Sie den Vorteil, dass Sie einer Funktion, wie bei tar gezeigt, Parameter übergeben können.
Damit lässt sich auch ein ganz auf die eigenen Bedürfnisse zurecht geschneiderter Download-Manager basteln. Wer etwa von einer Website nur die Bilder, Video- und Sound-Dateien herunterladen möchte, nicht aber Texte und die HTML-Seiten, erledigt das in der Shell normalerweise mit folgendem Bandwurm-Kommando:
wget -r -H -l1 -A jpg,gif,png,avi,mpg,mp3 www.adresse.de
Das Programm wget [3] zieht hier rekursiv (-r) alle Dateien vom Typ JPG, GIF, PNG, AVI, MPG oder MP3 von der Website www.adresse.de -- und zwar genau eine Ebene tief (-l1 für "Level 1"), d. h. er folgt den Links auf der angegebenen Adresse, aber nicht weiteren. -H sorgt dafür, dass wget auch Links zu anderen Servern folgt. Mit einer Shell-Funktion sparen Sie sich die Tipperei:
down() {
wget -r -H -l"$1" -A jpg,gif,png,avi,mpg,mp3 "$2"
}
Rufen Sie nun down 2 www.easylinux.de auf, erhalten Sie alle Dateien dieser Typen von der EasyLinux-Website. Wie man aus der Nummerierung erwarten kann, kennt die Shell nicht nur $1, sondern verpackt auch alle weiteren Argumente in nummerierte Variablen. Ein Leerzeichen trennt dabei jeweils eins vom anderen.
Optimal ist diese Funktion jedoch noch nicht. Was, wenn Sie statt einer URL mehrere angeben wollen? Direkt in der Shell aufgerufen, erledigt wget das ohne Murren, doch die Funktion liefert beim Versuch mit mehreren Adressen nur einen Fehler zurück. Theoretisch könnten Sie hinter "$2" noch "$3" und "$4" setzen, aber besonders elegant ist das nicht. Doch mit dem Befehl shift und der speziellen Variable $@ lösen Sie dieses Problem:
down() {
level="$1"
shift
wget -r -H -l"$level" -A jpg,gif,png,avi,mpg,mp3 "$@"
}
Hier verpacken Sie zuerst den Inhalt von $1 -- die Download-Tiefe -- in eine neue Variable namens level. shift schiebt dann alle übergebenen Parameter eins weiter nach links, aus $2 wird $1, aus $3 wird $2 usw. $@ schließlich enthält standardmäßig alle Parameter und übergibt sie gesammelt an den wget-Befehl. Damit ist der kleine Download-Manager fertig, Dateiendungen können Sie dort nach Gusto ergänzen (amü).
| Infos |
|
[1] Artikel über Packprogramme auf der Kommandozeile: Heike Jurzik, "Komprimierungskünstler", EasyLinux 07/2004 S. 84f. http://www.easylinux.de/Artikel/ausgabe/2004/07/084-guru-tar
[2] Alias-Artikel: Elisabeth Bauer, "Schleichwege", EasyLinux 07/2004 S. 82f. [3] wget-Artikel: Heike Jurzik, "Spieglein, Spieglein an der Wand...", EasyLinux 04/2004 S. 78ff. |
Dieser Online-Artikel kann Links enthalten, die auf nicht mehr vorhandene Seiten verweisen. Wir ändern solche "broken links" nur in wenigen Ausnahmefällen. Der Online-Artikel soll möglichst unverändert der gedruckten Fassung entsprechen.
Druckerfreundliche Version |
Feedback zu dieser Seite |
Datenschutz |
© 2012 Linux New Media AG |
Last modified: 2007-04-05 11:10
[Linux-Magazin]
[LinuxUser]
[Linux-Community]
[Admin-Magazin]
[Ubuntu User]
[Smart Developer]
[Linux Events]
[Linux Magazine]
[Ubuntu User]
[Admin Magazine]
[Smart Developer]
[Linux Magazine Poland]
[Linux Community Poland]
[Linux Magazine Brasil]
[Linux Magazine Spain]
[Linux Technical Review]