Aus Linux-Magazin 07/2011

Shellskripte aus der Stümper-Liga – Folge 15: Debugging und Konfigurationen

Auch jahrelang erprobte Konfigurationen kommen ins Schleudern, wenn Sonderfälle eintreten und sich etwa alle Anwender gleichzeitig von derselben IP-Adresse aus melden. Erfahrene Admins und Bash-Kenner aktivieren dann Debuggingfunktionen und suchen systematisch den Konfigurationsfehler.

Kommunikationsalarm beim Linuxtag in Berlin: Je mehr Vereinsmitglieder zum jährlichen Event in die bundesdeutsche Hauptstadt anreisen, desto schwieriger gestaltet es sich für sie, ihre E-Mail-Nachrichten per IMAP abzuholen. Dabei war die Netzanbindung vor Ort diesmal mehr als üppig dimensioniert, das System wohlgetestet, der Server wies eine Uptime von über 500 Tagen bei einer Load unterhalb von 0,4 auf. Trotzdem ließ sich keine Post abholen.

Massenandrang

Neu in diesem Jahr war, dass die Notebooks der Organisatoren vor Ort eine per NAT umgesetzte Adresse erhielten. In den Vorjahren – vermutlich noch nicht durch grassierende IP-Knappheit geplagt – wiesen die DHCP-Server des Linuxtag-Netzwerkteams ihren Kollegen noch öffentliche Adressen zu.

Hinter einem NAT-Gateway versteckt, scheint jedoch aus Sicht des IMAP-Servers jeder Anwender von derselben IP-Adresse aus zu kommunizieren. Manche Courier-Implementation des »imapd« beschränkt als Vorsichtsmaßnahme jedoch die Zahl der Verbindungen von einer IP. Eine solche Massenansammlung von Clients in einem privaten Netz hatte offenbar niemand vorgesehen.

Das Problem an sich erkannte die Technikabteilung der Veranstalter zwar bald, sah sich aber mit der Herausforderung konfrontiert, schnell die richtige Stelle zur Konfigurationsänderung zu lokalisieren. Die Entwickler des Courier-IMAP-Servers haben die Funktionalität nämlich auf ein halbes Dutzend Einzelprogramme aufgeteilt: Über einen »courierlogger« gestartet nimmt der »couriertcpd« zunächst alle Verbindungen auf TCP-Port 993 für SSL-verschlüsselte IMAP-Anfragen entgegen. Er entscheidet mittels eines Regelwerks, ob er von einem Host überhaupt Verbindungen akzeptiert.

Anschließend übergibt er an »couriertls« , einen weiteren Wrapper, der sich um den Aufbau der SSL-Verbindung kümmert. Er ruft schließlich über den weiteren Zwischenschritt »imaplogin« den eigentlichen »imapd« auf, der dem Client die gewünschten Nachrichten übermittelt.

Von Pontius …

Für jeden Systemverwalter gilt es mitunter herauszufinden, wie Programme sich gegenseitig aufrufen. Das ist insbesondere dann der Fall, wenn es darum geht, den kompletten Dienst mit seinen Programmen herunterzufahren, einen Parameter der Konfiguration zu ändern und anschließend wieder alles neu zu starten. So lässt sich etwa die Obergrenze der Clients pro IP neu justieren.

Ein vom Runlevel abhängiges Skript in »/etc/init.d« steuert diese Vorgänge. Im Zuge der voranschreitenden Modularisierung und Konfigurierbarkeit entwickelte sich aus einer einzelnen großen Datei »/etc/rc.local« aus alten BSD-Zeiten ein Konglomerat von Skipten und Parameterfestlegungen mit vielfältigen Konventionen. (Viele Admins beäugen die aktuell diskutierten designierten Nachfolger wie Upstart, Systemd und Konsorten gegenwärtig noch mit etwas Skepsis).

… zu Pilatus

Dem Systemadministrator hilft die Shelloption »-x« , um systematisch die Aufrufreihenfolge sichtbar zu machen. Fügt er mit einem Editor unterhalb der einleitenden Shebang-Zeile in »/etc/init.d/courier-imapd« die Anweisung

set -x

ein, schaltet diese die Bash in den Protokollmodus. Fortan tut die Shell nicht nur das, was man ihr sagt, sie spricht auch auf der Standardausgabe darüber. So erfährt der Admin mehr über eingelesene Konfigurationsdateien, gesetzte Parameter, angelegte Lockfiles und gestartete Subprozesse. In ganz schwierigen Fällen zeigt die Option »-e« ihren Nutzen: Sie sorgt nämlich dafür, dass das Skript sofort abbricht, falls auch nur ein Aufruf einen Fehlercode erzeugt. Wer im Normalfall das Skript

#!/bin/bash
ls
xy
id

mit den korrekten Aufrufen in der zweiten und vierten Zeile ablaufen lässt, erhält zwar eine Meldung über das fehlende Tool »xy« in Zeile 3, dann führt die Bash »id« aber trotzdem aus. Doch wer nach der Shellskript-Einleitungszeile die Option »set -e« setzt, sorgt dafür, dass das Skript nach »xy« abbricht.

Die beiden Flags bleiben übrigens für alle späteren Aufrufe dieser Shell aktiv, daher deaktiviert sie der Admin später durch »set +x« beziehungsweise »set +e« oder entfernt für künftige Aufrufe den Eintrag wieder aus dem Quelltext.

Saubere Trennung

Es gilt als vorbildliches Vorgehen, Code und Daten zu trennen, also insbesondere Konfigurationen nicht direkt in den Quelltext hineinzuschreiben, der die Einstellungen letztlich vornimmt. Von XML-Dateien über Whitespace-separierte Listen bis zu eigenen Konfigurationssprachen reicht das Spektrum der Formate für diesen Zweck. In der Bash bedienen sich Entwickler meist eines einfachen, da bereits eingebauten Mechanismus – der Zuweisung von Shellvariablen wie

maxconnections=30
PORT=993

in einer separaten Datei. Statt sie aufwändig manuell zu parsen, reicht es, sie als eigenes Skript auszuführen. Das gelingt scheinbar bereits durch das Angeben ihres Namens, etwa durch »./konfiguration.sh« . Als Problem stellt sich heraus, dass dadurch eine neue Shell entsteht, die ihre eigenen Variablen verwaltet. Das aufrufende Skript bekommt davon nichts mit (Abbildung  1).

Abbildung 1: Das Skript »ober.sh« ruft die Datei »unter.sh« auf, die beispielsweise Konfigurationsparameter setzen könnte. Dabei müssen Systemverwalter zwischen einem einfachen Aufruf, dem Export von Umgebungsvariablen und dem Sourcen von Skripten unterscheiden.

Abbildung 1: Das Skript »ober.sh« ruft die Datei »unter.sh« auf, die beispielsweise Konfigurationsparameter setzen könnte. Dabei müssen Systemverwalter zwischen einem einfachen Aufruf, dem Export von Umgebungsvariablen und dem Sourcen von Skripten unterscheiden.

Die Großschreibung von Variablen ändert daran entgegen einem verbreiteten Missverständnis übrigens nichts, wie das Verhalten von »APFEL« in Listing  1 und Listing  2 zeigt. Das Verwenden von Versalien ist nur eine Konvention, um Umgebungsvariablen zu kennzeichnen. Erst das Schlüsselwort »export« befördert Shellvariablen in diesen Rang.

Listing 1

ober.sh

01 #!/bin/sh
02
03 # Auskommentieren, um mehr zu sehen!
04 # set -x
05
06 echo "ich bin ober.sh"
07
08 echo "setze apfel auf rot, APFEL auf ROT"
09
10 apfel=rot
11 APFEL=ROT
12
13 echo "rufe unter.sh auf"
14
15 ./unter.sh
16
17 echo "exportiere nun APFEL"
18 export APFEL
19
20 ./unter.sh
21
22 echo "Wert von exportiertem APFEL"
23 echo "nach Rueckkehr aus Subshell: >$APFEL<."
24
25 echo "apfel hat nun den wert >$apfel<."
26
27 echo "source nun unter.sh"
28
29 . ./unter.sh
30 # alternative Schreibweise: source ./unter.sh
31
32 echo "apfel hat nun den wert >$apfel<."
33 exit 0

Listing 2

unter.sh

01 #!/bin/sh
02
03 echo "dies ist unter.sh"
04
05 echo "apfel hat jetzt den Wert >$apfel<."
06 echo "APFEL hat jetzt den Wert >$APFEL<."
07
08 echo "aendere den Wert auf gruen:"
09
10 apfel=gruen
11 APFEL=GRUEN

Aber auch dieser Kniff hilft nicht beim Einlesen von Konfigurationseinstellungen, wie die Ausgabe der Testskripte zeigt: So lassen sich zwar Daten in ein Unterprogramm hineinsenden, aber nicht wieder herausholen. Dazu ist das Schlüsselwort »source« notwendig, das auch unter dem Kürzel eines allein stehenden ».« firmiert (Zeile 29 in Listing  1). In diesem Fall behandelt die Bash das untergeordnete Skript so, als hätte es dessen Quelltext in das aufrufende kopiert.

Wirre Wendungen

Die Wege manches Start- oder Konfigurationsskripts sind verworren, aber nicht unergründlich. Die Shelloptionen »-x« oder »-e« helfen dem Admin beim systematischen Suchen. Genaues Hinsehen ist beim Einbinden von Konfigurationsdateien gefragt, denn ein einzelner Punkt ».« als Abkürzung für das Shellkommando »source« [1] bewirkt große Unterschiede zur normal aufgerufenen Subshell.

Mit diesem Handwerkszeug lokalisierten die Linuxtag-Admins dann auch den Parameter »MAXPERIP« und erhöhten ihn so weit, dass die Organisatoren der Linux-Großveranstaltung wie erwartet ihre Tore öffnen konnten.

Infos

  1. Mendel Cooper, “Subshells”, Advanced Bash Scripting Guide: http://www.tldp.org/LDP/abs/html/subshells.html
DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 2 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben