Open Source im professionellen Einsatz

LPIC-1-Vorbereitung - Teil 9: Shell anpassen und Skripteschreiben

Großer Shell-Atlas

Das LPI-Zertifikat setzt den sicheren Umgang mit der Shell voraus. Administratoren müssen aber auch in der Lage sein, die Bash zu konfigurieren und nützliche Skripte zu programmieren. Die LPIC-Serie stellt diesmal die Prüfungsthemen aus Topic 109 vor.

Die Standardshell unter Linux ist die Bash. Auch wenn es die C-Shell, Tcsh, Korn-Shell und viele weitere gibt, die ebenfalls ihre Anhänger haben, sind für die LPI-Prüfung nur Bash-Kenntnisse relevant. Bei dem dabei abgefragten Wissen geht es um Shellvariablen, Skripte und die Konfiguration des Shellstarts über Profile-Dateien.

Shellvariablen setzt der Anwender mit »Variable=Wert« und ruft sie später durch ein vorangestelltes Dollarzeichen ab, etwa »echo . Häufig enthalten Shellskripte statt dieser einfachen Variante die Form »«. Sie macht zum einen deutlicher, an welcher Stelle der Name aufhört (Was bedeutet ».AZ«?), zum anderen ist es bei Zusammensetzungen manchmal die einzige Möglichkeit, Variablen und Strings zu kombinieren:

$ X="AAA"; Y="BBB"; XY="CCC"
$ echo $XY; echo ${XY}; echo ${X}Y; echo $X$Y
CCC
CCC
AAAY
AAABBB


Jeder Prozess besitzt eine eigene Umgebung, in der Umgebungsvariablen definiert sind. Über den »export«-Befehl der Bash wird eine Shell- zur Umgebungsvariablen. Letztere gibt das System beim Erzeugen neuer Prozesse weiter: Nach dem Start eines Programms aus der Shell erbt der neue Prozess alle Umgebungsvariablen, nicht aber die Shellvariablen, wie folgendes Beispiel zeigt:

$ SHELLVAR=Test1
$ export UMGEBUNGSVAR=Test2
$ bash
$ echo $SHELLVAR
$ echo $UMGEBUNGSVAR
Test2


Das »export«-Kommando wandelt eine bereits definierte Shellvariable zur Umgebungsvariablen: »export Variable«. Der Befehl »env« zeigt die Liste aller exportierten Variablen an (Abbildung 1), »set« tut das auch, liefert aber außerdem die definierten Shellfunktionen zurück. Das Exportieren ist übrigens keine Einbahnstraße: Der Befehl »export -n Variable« macht aus einer Umgebungs- wieder eine Shellvariable, nimmt also einen früheren »export«-Aufruf zurück. Um eine Variable ganz zu löschen, bietet die Bash das Kommando »unset«.

 

Eine andere Möglichkeit, gestarteten Prozessen eine Variable zu übergeben, ist es, die Variablenzuweisung unmittelbar vor den Programmaufruf zu setzen:

Variable=Wert Kommando


Ein Beispiel dafür ist »VISUAL=nedit less lpi-shell.txt«. Dieser Befehl zeigt die Textdatei in »less« an und definiert vorher die Variable »VISUAL«, die der Dateibetrachter auswertet, wenn er einen Editor startet.

Startdateien

Zahlreiche Shellvariablen sind schon nach dem Shellstart definiert, dafür sind die Startdateien verantwortlich, welche die Shell aufruft. Dabei spielt es eine Rolle, ob die Shell eine Login-Shell oder eine normale interaktive (aber nicht durch Login gestartete) ist: Es gibt einige Skripte, die nur beim Login - also beim ersten Aufruf einer Shell in einer neuen Benutzersitzung - relevant sind, während die Shell andere Skripte bei jedem Start liest. Eine nicht interaktive Shell ist eine, die nur läuft, um beispielsweise eine Skriptdatei auszuführen, sie liest darum keine Startskripte ein.

Jede Login-Shell arbeitet zunächst die »/etc/profile«-Datei ab, wenn es sie gibt. Danach sucht die Shell im Homeverzeichnis nach »~/.bash_profile«, »~/.bash_login« und »~/.profile«. Die in dieser Reihenfolge zuerst aufgefundene erhält den Zuschlag. Ist die Shell keine Login-Shell, führt sie stattdessen die Dateien »/etc/bash.bashrc« und »~/.bashrc« aus, sofern vorhanden.

Je nach Distribution gibt es noch mehr Startup-Dateien. So sucht die Bash unter Suse Linux nach »/etc/profile.local« und »/etc/profile.dos«. Außerdem gibt es ein Verzeichnis »/etc/profile.d/«: Jedes Shellskript, das darin liegt und dessen Name auf ».sh« endet, führt »/etc/profile« zusätzlich aus.

Auch beim Verlassen einer Login-Shell finden letzte Aktivitäten statt, wenn es eine Datei »~/.bash_logout« gibt. Wer herausfinden will, welche Datei die Shell wann ausführt, trägt einfach kurze Statusmeldungen der Form »echo in /etc/profile« in die Startdateien ein (siehe Kasten "Bash-Startupskripte").

LPI-Aufgabengruppen

Das Linux Professional Institute gliedert die Prüfungsfragen in Aufgabengruppen. Dieser Artikel erklärt die Abschnitte:

  • 1.109.1 Anpassung und Benutzung der Shellumgebung
  • 1.109.2 Anpassen oder Schreiben einfacher Skripte

Bash-Startupskripte

Wer herausfinden will, wann die Shell welche Startskripte abarbeitet, kann nach folgender Anleitung vorgehen. Sie ergänzt (beispielhaft auf einem Suse-Linux-System) die globalen Dateien »/etc/bash.bashrc« und »/etc/profile« sowie die benutzereigenen Dateien »~/.profile«, »~/.bashrc« und »~/.bash_logout« um Hello-World-Zeilen der Form:

echo ... in Dateiname


Für Login-Shells ergibt sich folgendes Bild:

login: Username
Password:
Last login: Thu Feb 15 16:39:55 from localhost
Have a lot of fun...
... in /etc/profile
... in /etc/bash.bashrc
... in ~/.bashrc
... in ~/.profile
$ logout
... in ~/.bash_logout


Für normale Shells sieh es hingegen so aus:

$ bash
... in /etc/bash.bashrc
... in ~/.bashrc
$ exit


Beim Start von Shellskripten, die ja selbst auch den Aufruf einer neuen Shell bewirken, erscheinen gar keine Meldungen, da es sich um keine interaktiven Shells handelt. Wer auch in einem Shellskript das Ausführen dieser Dateien erzwingen will, setzt in die erste Zeile zusätzlich die Bash-Option »-i« (interaktiv) oder »--login« (Login-Shell):

#!/bin/bash --login


Dann verhält sich die Shell entsprechend der gesetzten Option.

Rückgabewerte

Externe Programme wie auch eingebaute Funktionen geben einen Wert an die Shell zurück: Der steht nach dem Aufruf in der Spezialvariablen »$?«, aber nur bis zum nächsten Befehlsaufruf:

$ gfdgfd; echo $?
bash: gfdgfd: command not found
127


Der Rückgabewert »0« bedeutet, dass der Befehlsaufruf erfolgreich war; alle anderen Werte stehen für einen Fehler. Je nach Programm haben die Fehlerwerte unterschiedliche Bedeutungen.

Über die Operatoren »||« (logisches Oder) und »&&« (logisches Und) ist eine bedingte Verknüpfung mehrerer Kommandos möglich: So führt »Befehl1 && Befehl2« dazu, dass die Shell den zweiten Befehl nur dann ausführt, wenn der erste Aufruf erfolgreich war, also »Befehl1« den Rückgabewert »0« hatte. Ein Beispiel dafür ist die Verknüpfung der Befehle aus dem klassischen Kompilier-Dreischritt: Schreibt der Anwender

./configure && make && make install


dann startet »make« nur, falls das Configure-Skript erfolgreich durchgelaufen ist. Genauso verzichtet die Shell auf den Aufruf von »make install«, wenn es bei den vorherigen zwei Kommandos zu Fehlern kam. Der »||«-Operator arbeitet ähnlich. Hier führt die Shell in der Sequenz »Befehl1 || Befehl2« das zweite Kommando aber nur dann aus, wenn das erste mit einem Fehler endete:

$ cat /etc/shadow 2>/dev/null || echo Darf Shadow-Datei nicht lesen
Darf Shadow-Datei nicht lesen


Die obige Ausgabe ist ein Beispiel für diesen Zusammenhang.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 4 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Als digitales Abo

Als PDF im Abo bestellen

comments powered by Disqus

Ausgabe 07/2013

Preis € 6,40

Insecurity Bulletin

Insecurity Bulletin

Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...

Linux-Magazin auf Facebook