Wer sein System permanent überwacht, hat den Grundstein dafür gelegt Engpässe zu vermeiden und Fehler frühzeitig zu erkennen. Neben dem Platzhirsch Nagios ... (mehr)

Multipel

Listing 7 zeigt eine Alternative zum in Listing 1 vorgestellten SSH-Skript. Es kombiniert die verschiedenen Expect-Anweisungen in eine einzige, die auch wie eine Schleife funktioniert. Das Skript beginnt wie üblich mit der Zuweisung einiger Variablen. Außerdem zeigt es, wie man eine Umgebungsvariable in einem Expect-Skript verwendet: Der Ausdruck »$env(NAME)« gibt den Wert der Umgebungsvariable »NAME« zurück. So vermeidet es das Skript, einen Benutzernamen fest zu verdrahten und bezieht ihn stattdessen aus der Umgebungsvariablen »USER« . Die »expect« -Anweisung umfasst vier Blöcke:

Listing 7

SSH

 

  • »(yes/no?)« : Der bekannte Prompt vom SSH-Schlüsselaustausch. Wird dieser String gefunden, schickt das Skript die Antwort »yes« und fährt wegen der Anweisung »exp_continue« fort.
  • »word:« : Der Passwort-Prompt, den das Skript mit dem Passwort beantwortet. Daraufhin gibt das Skript eine Meldung aus, in der es darüber informiert, dass der Schlüsselaustausch noch nicht abgeschlossen ist. Die Anweisung »send_tty« gibt den String immer am Bildschirm aus, egal wohin die Standardausgabe gerade umgeleitet ist. Auch hier macht das Skript wegen der Anweisung »exp_continue« weiter.
  • »(|#|>)« : Eine Regular Expression, die drei Varianten eines Shell-Prompts abdeckt. Findet das Skript eines dieser Zeichen, begibt es sich nicht per »interact« in den interaktiven Modus. An dieser Stelle endet das Skript dann.
  • »timeout« : Dieses Label wird erreicht, wenn in der vorgegebenen Zeit keine Antwort vom SSH-Befehl zurückkommt. Das Skript gibt eine entsprechende Meldung aus und endet.

Obwohl das eben vorgestellte Expect-Skript sehr nützlich ist, weist es ein kleines bis mittleres Security-Problem auf: Das Passwort steht im Klartext im Skript. Das ist im Allgemeinen keine besonders gute Idee, und man sollte das Skript wenigstens an einem sicheren Ort mit den entsprechenden Rechten verstauen. Das nächste Skript umgeht dieses Problem. Es zeigt, wie man vom Benutzer am Anfang ein Passwort einliest und es dann später verwendet.

Listing 8 zeigt den ersten Teil des Skriptes, das die Kommandozeilenargumente verarbeitet: die auf den anderen Rechner zu kopierende Datei und den Usernamen auf dem anderen Rechner (im Default-Fall Root). Es liest eine Datei namens »xferhosts« im aktuellen Verzeichnis ein, das eine Liste der Hosts enthält, auf die die Datei kopiert werden soll. Dieser Code kann als Blaupause dafür dienen, mit Tcl Dateien aus einer externen Datei zu lesen:

Listing 8

Argumente verarbeiten

 

set file [open "xferhosts" r]
set hlist [split [read $file] "\n"]
close $file

Dann fragt das Skript das Passwort auf dem anderen Rechner ab. Dazu schaltet »-echo« die Anzeige der Eingabe aus, »echo« entsprechend später wieder ein:

stty -echo
send_tty "_"
expect_tty "\n"
set pwd [string trimright "$expect_out(buffer)" "\n"]
stty echo
if {$pwd == ""} { exit }

Die Set-Anweisung, die die Variable »pwd« belegt, liest per Tcl den Inhalt aus dem Expect-Puffer. Er besteht aus allen Zeichen, die Expect von dem vorigen Match bis zum aktuellen gelesen hat. In diesem Beispiel ist es das, was der Benutzer nach dem Passwort-Prompt eingegeben hat. Das Skript entfernt das Newline, das die Eingabe abschließt und zuerst noch Teil des Strings ist.

Listing 9 zeigt die Schleife über die Liste der Hosts aus der Datei. Die Tcl-Anweisung »foreach« liest einen nach dem anderen, die If-Anweisung sorgt dafür, dass der Hostname nicht leer ist. Die »expect« -Anweisung ist ähnlich zu der im letzten Beispiel. Es kümmert sich um den Schlüsselaustausch und den Passwort-Prompt, wenn sie auftreten, und beendet die Schleife mit »break« , wenn das Skript zu lange warten muss.

Listing 9

Schleife über eine Liste

 

Der andere Fall in der »expect« -Anweisung ist eine Regular Expression, die einem beliebigen Zeichen entspricht. Das »scp« -Kommando sendet während der Arbeit Zeichen. Solange man welche empfängt, weiß man also, dass es noch läuft. Wenn die Regular Expression matcht, läuft exp_continue ab, was die Schleife fortsetzt und auch den Timeout zurücksetzt.

Prompt mit Timeout

Die Bash-Shell bietet einen Weg, Benutzereingaben mit »read« einzulesen und in einer Variablen zu speichern, wie im folgenden Beispiel:

read -p "Prompt string: " answer < /dev/tty

Ein solcher Prompt wird ewig auf eine Eingabe warten. Manchmal will man aber nur eine Zeit lang einen Prompt anzeigen und dann weitermachen, wenn nichts passiert. Expect bietet mit wenig Aufwand solche Prompts mit eingebautem Timeout. Das zugehörige Skript in Listing 10 beginnt wieder damit, die Argumente zu verarbeiten. Der Default-Prompt ist »Enter response« , der Default-Timout fünf Sekunden. Der folgende Code zeigt den Teil des Skriptes, der den Prompt-String anzeigt und die Benutzereingabe verarbeitet, wenn es eine gibt:

Listing 10

Prompt und Timeout

 

send_tty "$prompt: "
set timeout $tout
set response ""
expect "\n" {
 set response [string trimright "$expect_out(buffer)" "\n"]
}
send $response

Das Skript zeigt den Prompt am Bildschirm an, setzt den Timeout-Wert und weist der Variablen, die die Antwort speichert, einen Anfangswert zu. Die »expect« -Anweisung ändert den Wert auf die Eingabe des Benutzers. Das Skript endet damit, den Antwortwert zurückzugeben.

Listing 11 zeigt ein Beispiel dafür. Die folgenden Zeilen zeigen, wie das Skript abläuft, wenn man bei der zweiten Eingabeaufforderung einen Wert eingibt, nicht aber bei der ersten:

Listing 11

Anwendung

 

$ ./use_prompt
What is your favourite color?
Your color is red
What is your favourite color? green
Your color is green

Beim ersten Mal gibt das Skript die Default-Farbe (rot) aus, im zweiten Fall die Farbe, die der Benutzer eingibt.

comments powered by Disqus
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023