Open Source im professionellen Einsatz

Shellskripte aus der Stümper-Liga – Folge 17: Frage und Antwort

Bash Bashing

Soll ein Shellskript mit seinen Benutzern interagieren, braucht der zuständige Bash-Programmierer auf den Spatz nicht gleich mit der GUI-Toolkit-Kanone samt zusätzlicher Programmiersprache zu schießen. Wie das Kleinkaliber funktioniert, beschreibt dieser Artikel.

Unter [1] findet sich ein praktisches Skript für Wartungsarbeiten an Wordpress-Datenbanken, seine ersten Zeilen zeigt Listing 1. Für den Datenbankzugriff braucht das Skript das zugehörige Passwort – der Programmierer hat sich offenbar der Einfachheit halber dazu entschlossen, dass der Benutzer es dem Skript als Parameter übergibt.

Mal abgesehen davon, dass das ganze Parameter-Handling nicht besonders robust gelöst ist, stellt die Übergabe von Passwörtern auf der Kommandozeile ein Sicherheitsrisiko dar. Denn jeder Benutzer kann die Prozessliste mit allen Parametern auslesen. Um diesen Designfehler zu vermeiden, muss das Skript selbst den Benutzer nach dem Datenbank-Passwort fragen, dessen Antwort entgegennehmen und verarbeiten.

Listing 1

wordpress-cleanup

01 #! /bin/bash
02
03 # Korrekte Parameteranzahl überprüfen
04 if [ $# -ne 4 ];
05 then
06    echo "Usage: wordpress-cleanup <Database> <Table-Prefix> <Username> <Password>"
07    exit 0
08 fi
09
10 # Variablen deklarieren
11 DATABASE=$1
12 WPPREFIX=$2
13 USERNAME=$3
14 PASSWORD=$4
15
16 # MySQL-Queries ausführen
17 mysql -u$USERNAME -p$PASSWORD $DATABASE <<EOF
18 [...]

Es kann kaum überraschen, dass die Bash auch für dieses Problem eine Lösung parat hält. Die Passwortabfrage ist aber nur ein Spezialfall für die Benutzereingabe einzeiliger Texte. Die Bash hat dafür den Befehl »read« und neuerdings »readarray« eingebaut. In Listing 2 verhindert die »read« -Option »-r« (für raw), dass ein Backslash als Escape-Zeichen wirkt. Die Option »-e« weist den Befehl an, die Readline-Bibliothek zu nutzen – der Anwender darf Bash-typisch in der Zeile navigieren.

Die Zeile 2 im Listing ist die klassische Passwortabfrage mit der »-s« -Option (für silent). Bei der letzten Variante führt »"-N 1"« dazu, dass der Anwender nur einen Buchstaben eingeben muss. Aus GUI-Sicht handelt es eher um eine Messagebox als um ein Eingabefeld.

Die Beispiele haben jeweils als letztes Argument nur eine Variable. Fehlt sie, schreibt Read den eingegebenen Wert in die Variable »REPLY« . Bei mehr als einer Variablen parst der Read-Befehl die Antwort. Read kennt noch ein paar Optionen mehr, die Manpage zur Bash gibt darüber ausreichend Auskunft.

Listing 2

Eingabefeld mit Bash-Mitteln

01 read -r -e -p "Bitte Wert eingeben: " zeile
02 read -p "Passwort: " -s passw
03 read -p "Sind Sie sicher? J/N: " -N 1 antwort

Längere Texte erfassen

Im manchen Fällen ist eine Zeile Eingabetext aber zu wenig. Wer längere Texte abfragen will, startet einfach einen Editor. Per Konvention steht der bevorzugte Editor in der Variablen »EDITOR« . Ist diese nicht gesetzt, dann ist der Vi die sicherste Wahl. Mit Bash-Mitteln gelingt es aber auch:

echo "Eingabe mit Strg-D beenden:"
textFeld="$(</dev/stdin)"

Die Anführungszeichen sind wichtig, ansonsten ersetzt die Bash die Zeilenumbrüche durch Leerzeichen. Diese Form ist sehr einfach und kompakt, verschafft dem Anwender aber keine Gelegenheit, im geschriebenen Text zu navigieren und Korrekturen durchzuführen.

Menüs und Auswahllisten

Menüs und Auswahllisten zaubert der Bash-Befehl »select« auf den Bildschirm. Ein Beispiel zeigt Listing 3. Es beschreibt einen einfachen Logfile-Browser, bei dem der Benutzer die gewünschte Datei nicht erst über »ls« suchen muss, sondern das Skript bietet ihm eine Liste zum Auswählen an. Der Befehl »select name in ...« führt alle Wörter in der »in« -Liste als einzelne Listenpunkte auf und gibt daraufhin den PS3-Prompt aus. Das Beispiel setzt den Prompt in Zeile 3. Jetzt kann der Benutzer eine der vordefinierten Nummern eingeben, aber auch andere Antworten sind möglich.

Nur im ersten Fall landet der Wert der ausgewählten Nummer in der »select« -Variablen. Bei falscher Eingabe ist die Variable leer. Die eigentliche Eingabe des Anwenders, also die Nummer oder sonstiger eingegebener Text, landet immer in der Shellvariablen »REPLY« . Mit einem Dateiende-Zeichen ([Strg]+[D]) beendet der Benutzer die Auswahl.

Listing 3

Auswahlliste per select

01 #!/bin/bash
02
03 PS3="Auswahl der Log-Datei: "
04 select logfile in /var/log/messages* quit; do
05   echo -e "Log-Datei: $logfile\nAuswahl: $REPLY"
06   if [ -n "$logfile" ]; then
07     case "$logfile" in
08       quit) exit 0;;
09       *) less "$logfile";;
10     esac
11   elif [ "$REPLY" = "quit" -o "$REPLY" = "q" ]; then
12     exit 0
13   else
14     echo "Fehlerhafte Eingabe!" >&2
15   fi
16 done

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 2 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