Das Paket expect bietet die Möglichkeit Scripte zu erstellen, die auf bestimmte Ausgaben anderer Programme warten und darauf reagieren. Das funktioniert auch bei entfernten Rechnern, wie ich mit folgendem fiktiven Beispiel zeigen möchte.
Es wird dabei angenommen, dass das Administrations-Passwort auf mehreren Servern automatisch geändert werden soll. Der Einfachheit halber geht das Script davon aus, dass alle Server das gleiche Administrationspasswort haben, was der Sicherheit nicht unbedingt zuträglich ist.
Auf dem ausführenden Rechner muss natürlich das Paket expect installiert sein.
Zugangsdaten für expect
Die Zugangsdaten bekommt expect aus einer csv-Datei pw_list.csv, in der der Admin-Kontoname, das aktuelle Passwort und das neue Passwort stehen. Diese Datei sieht dann z.B. so aus.
admin huThz%d#lhIFt UE4s#jkl!zqJdER
Das Script prüft nicht auf Return- und New-Line-Codes, so dass am Ende der Zeile kein RETURN stehen darf.
Die Liste der IP-Adressen
Die IP-Adressen der Rechner stehen in einer zweiten csv-Datei ip_list.csv, die in jeder Zeile eine Adresse enthält, um sie mit read LINE einzulesen. Auch hier sollte am Ende kein RETURN stehen, damit das Script sich sauber beendet.
10.10.1.200 10.10.1.201 10.10.1.202 10.10.2.200
Das Startscript
Das Startscript kümmert sich um das Einlesen der Variablen und ruft für jede IP-Adresse in der ip_list.csv das expect-Script pw_expect.sh auf.
Im Einzelnen passeirt folgendes: In Zeile 5 und 6 werden die Dateinamen in Variablen geschrieben und in Zeile 7 bis 11 die Zugangsdaten eingelesen. Danach wird jede IP-Adresse aus der IP-Liste ip_list.csv abgearbeitet.
Durch das sleep 10 hat man am Bildschirm die Möglichkeit, das Ergebnis für jede Adresse zu überprüfen. Da im expect-Script ein LOG-File definiert wird, wird die Bildschirmausgabe auch mit protokolliert.
#!/bin/bash # pw_change.sh # Vatiablen belegen IPLIST="ip_list.csv" PWLIST="pw_list.csv" while read LINE; do ADMIN="$(echo "$LINE" | awk '{print $1}')"; OLDPW="$(echo "$LINE" | awk '{print $2}')"; NEWPW="$(echo "$LINE" | awk '{print $3}')"; done < $PWLIST # IP-Liste abarbeiten while read LINE; do IPSRV="$(echo "$LINE")"; expect pw_expect.sh $ADMIN $IPSRV $OLDPW $NEWPW sleep 10 done < $IPLIST
Das expect-Script
Zeile 5 setzt zunächst mal den Timeout für expect auf unendlich. Danach werden die von pw_change.sh übergebenen Werte in Variablen eingelesen und mit spawn ssh die Verbindung zum Rechner hergestellt. Die vom Zielrechner erwarteten Zeichenketten sind hier sehr verkürzt, um sowohl deutsche als auch englische Systeme abdecken zu können.
#!/usr/bin/expect #pw_expect.sh log_file expect.log set timeout -1 set eadmin [lindex $argv 0] set eipsrv [lindex $argv 1] set eoldpw [lindex $argv 2] set enewpw [lindex $argv 3] spawn ssh $eipsrv -l $eadmin expect { "word: " { send "$eoldpw\r" } "(yes/no)?" { send "yes\r" exp_continue } "word: " { send "$eoldpw\r" } } expect { "$ " { send "passwd\r" } } expect { "UNIX*: " { send "$eoldpw\r" } } expect { "n*UNIX*: " { send "$enewpw\r" } } expect { "*UNIX*: " { send "$enewpw\r" } } expect { "$ " { send "logout\r" } } expect eof
Wird eine Zeichenfolge in der Konsole ausgegeben, die von expect erwartet wird. dann wird der Inhalt der Variablen oder ein Text gesendet.
In Zeile 11 bis 13 sieht man, wie man zwei unterschiedliche Möglichkeiten auswertet. Verbindet man sich bei per SSH mit einem Rechner das erste Mal, dann wird nicht sofort das Passwort abgefragt, sondern zuerst die Bestätigung für den Schlüssel angezeigt, die man mit yes bestätigen muss und erst danach kommt die Passwortabfrage.
Der Aufbau ist wie bei einer OR-Verknüpfung mit dem Unterschied, dass nach dem Erkennen des (yes/no)? in Zeile 12 durch exp_continue auch Zeile 13 noch ausgeführt wird. Bei einer OR-Verknüpfung (also ohne exp_continue) würde nur eine der drei Möglichkeiten abgearbeitet.
Fehlerbehebung
Treten Fehler auf, dann ist die erste Wahl, expect in Zeile 16 von pw_change.sh mit dem Parameter -d aufzurufen.
Was ich hier gezeigt habe, ist nur ein sehr kleiner Ausschnitt aus den Fähigkeiten des Pakets expect.
Weitere Informationen und Beispiele findet man dazu auf der -> Manpage.
Ähnliche Beiträge:
-> Dateien mit Batch-Script umbenennen
-> Bildschirmauflösung von Raspberry-Pi in der Virtualbox ändern