Aus Raspberry Pi Geek 05/2014

Erste Schritte mit Bash-Skripten (Seite 4)

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).

Listing 7

 

#!/bin/bash
PATH=/bin:/usr/bin                # setzt den Pfad
. /usr/local/sbin/functions.bash  # Datei hier einbinden
printf "USER\tGB USED\n"          # Kopfzeile für Bericht drucken
for WHO in $(</usr/local/sbin/ckusers); do
  HOMESUM=`eval du -s ~$WHO | awk '{print $1}'`
  TMPLIST=$( ls -lR --block-size 1024 $(</usr/local/bin/ckdirs) |\
             egrep "^.......... +[0-9]+ $WHO" | awk '{print $5}' )
  TSUM=0
  for N in $TMPLIST; do
    TSUM=$(( $TSUM+$N ))
  done
  TOT=$(( $HOMESUM+$TSUM ))
  to_gb $WHO $TOT
done

Eine For-Schleife bildet das zentrale Konstrukt dieses Skripts. Innerhalb der Schleife erhält eine Variable bei jedem Durchgang einen neuen Wert. Das Schlüsselwort in verweist auf die Liste von Werten, der separate Befehl do leitet die eigentlichen Operationen ein. Die Schleife endet mit done, sobald sie alle Elemente der Liste abgearbeitet hat.

Im Beispiel erhält die Variable WHO immer das nächste Element aus der Datei ckusers. Das Konstrukt $(<file) arbeitet als Abkürzung für $(cat file).

Die Definition von HOMESUM verwendet ein Backtick-Konstrukt, um die Gesamtgröße des Home-Verzeichnisses eines Benutzers aus der Ausgabe von du -s via Awk zu extrahieren. Der Befehl eval bewirkt, dass das Kommando du das Konstrukt ~$WHO als Tilde-Schreibweise für das Benutzerverzeichnis interpretiert.

Die Definition von TMPLIST verwendet Befehlssubstitution zum Herausfiltern und Einfügen des Größe-Feldes aller Zeilen (via Awk) in der Ausgabe von ls -lR, die den Elementen des aktuellen Benutzers entsprechen (festgestellt durch Egrep). Der Befehl ls prüft alle Verzeichnisse, die die Datei ckdirs auflistet. Er verwendet die Option --block-size, um das Ergebnis in der gleichen Größenordnung anzuzeigen, wie es du verwendet (KByte).

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 9 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben