Listing 5
#!/bin/bash
if [ $# -lt 1 ]; then # kein Argument: Eingabeaufforderung
read -p "Wen wollten Sie überprüfen? " WHO
if [ -z $WHO ]; then # kein Name wurde eingetragen
exit 0
fi
else
WHO="$1" # speichert das Argument
fi
LOOK=$(w | grep "^$WHO")
if [ $? -eq 0 ]; then # vorigen Befehlsstatus prüfen
WHEN=$(echo $LOOK | awk '{print $4}')
echo "$WHO ist angemeldet seit $WHEN."
else
echo "$WHO ist zurzeit nicht angemeldet."
fi
exit 0
Dieses Skript prüft zuerst, ob die Dame ein Argument in der Befehlszeile angegeben hat. Falls nicht (Anzahl der Argumente kleiner als 1), erscheint eine Eingabezeile zur Angabe des gewünschten Benutzers. Dabei kommt der eingebaute Befehl read zum Einsatz. Die Eingabe landet in der Variable WHO.
Hat WHO nach der Abfrage immer noch die Länge null, hat die Sekretärin keinen Benutzernamen eingetippt, sondern lediglich [Eingabe] gedrückt. In diesem Fall beendet sich das Skript. Ansonsten erhält WHO das in der Befehlszeile angegebene Argument als Wert.
Der zweite Teil des Skripts verwendet zwei Konstrukte mit Befehlssubstitution. Das erste sucht in der Ausgabe des Befehls w nach dem gewünschten Benutzernamen und speichert die entsprechende Zeile in LOOK. Die zweite definiert die Variable WHEN als das vierte Feld dieser Ausgabe (Zeitpunkt der letzten Anmeldung).
Dieses Feld extrahieren Sie mittels Awk. Sie brauchen das Tool nicht in- und auswendig zu kennen, um diesen einfachen Trick anzuwenden. Dabei kommt der Befehl nur zum Einsatz, wenn der Wert der Variable $? gleich 0 ist. Sie enthält den Statuscode des letzten Befehls, in diesem Fall also jenen von Grep. Liegt ein Ergebnis vor, hat sie den Wert 0, sonst den Wert 1.
Zum Abschluss zeigt das Skript eine entsprechende Meldung mit dem Status des Benutzers:
emoglen ist angemeldet seit 08:47.
Fragt jetzt jemand nach emoglen, kann die Sekretärin beruhigt die Auskunft geben, der sei derzeit an seinem Rechner beschäftigt.
Schleifen binden
Das Skript aus Listing 6 demonstriert eine weitere Verwendung von while und read: das Verarbeiten aufeinanderfolgender Zeilen einer Ausgabe oder einer Datei. Der Zweck des Skripts liegt im Versenden von Mails an Benutzer in einer Liste als separate Nachrichten.
Listing 6
#!/bin/bash /bin/cat /usr/local/sbin/email_list | while read WHO WHAT SUBJ; do /usr/bin/mail -s "$SUBJ" $WHO < $WHAT echo $WHO done
Das Skript sendet über eine Pipe (|) den Inhalt der entsprechenden Datei an die While-Schleife. Die liest mittels read die Zeilen und speichert deren Inhalt in drei Variablen. Das erste Wort einer Zeile landet in WHO, das zweite in WHAT und alle weiteren in SUBJ. Diese enthalten anschließend die Mailadresse, den Inhalt der Nachricht in einer Datei sowie den Betreff für jede Person. Die Variablen kommen beim Erstellen des nachfolgenden Mail-Befehls zum Einsatz.
Beachten Sie, dass dieses Skript den vollständigen Pfadnamen für externe Befehle verwendet. Am besten geben Sie immer den vollständigen Pfadnamen an oder fügen eine PATH-Definition am Anfang des Skripts hinzu, um eventuelle Probleme mit den Berechtigungen von ausführbaren Dateien bei der Substitution zu vermeiden.
In Sachen Sicherheit geht dieses Skript viel zu lässig mit dem Inhalt der Datei email_list um und vertraut darauf, dass diese ordnungsgemäß formatierte Mailadressen enthält. Möchten Sie das Skript weitergeben, gilt es die Adressen sorgfältig zu überprüfen. So besteht zum Beispiel die Möglichkeit, dass ein Nutzer eine Eingabe in der Form [email protected]; /irgendwo/run_me in der Adressenliste versteckt. Das führt dazu, dass das Programm run_me unerlaubt startet.
Schleifen
Die nächsten beiden Skripte veranschaulichen andere Arten von Schleifen, die Sie in Shell-Skripten über den for-Befehl anwenden können. Listing 7 erstellt einen Bericht über den belegten Speicherplatz samt einer Liste von Verzeichnissen für eine Reihe von Anwendern.
Die Dateien mit der Liste der Benutzer und der zu prüfenden Verzeichnisse finden sich hier explizit im Skript, Sie können aber auch Optionen dafür setzen. Das Skript beginnt mit der Angabe des Pfads und dem Einbeziehen einer anderen Datei in das Skript mithilfe des Include-Datei-Mechanismus, dem sogenannten Punktbefehl (aufgerufen mit einem Punkt).

