fragen stichworte

Erwarte ein Timeout in Bash-Skripten

Wie füge ich im folgenden Skript eine Zeitüberschreitung für "Erwarten" hinzu? Ich möchte es als 120 Sekunden einstellen.

#!/bin/bash
HOST="localhost"
USER="myuname"
PASS="mypassword"

VAR=$(expect -c "
spawn ssh $USER@$HOST
expect \"password:\"
send \"$PASS\r\"
expect \"\\\\$\"
send \"ls\r\"
expect -re \"$USER.*\"
send \"logout\"
")

echo "==============="
echo "$VAR"

antworten

Das Standard-Timeout für expect beträgt laut seiner Manpage 10 Sekunden. Um es auf 120 Sekunden vor spawn ssh $USER@$HOST zu ändern, fügen Sie die Zeile

hinzu
set timeout 120

um dies zu machen

VAR=$(expect -c "
set timeout 120
spawn ssh $USER@$HOST
expect \\"password:\\"
send \\"$PASS\\r\\"
expect \\"\\\\\\\\$\\"
send \\"ls\\r\\"
expect -re \\"$USER.*\\"
send \\"logout\\"
")

Entsprechend dem folgenden Auszug der Manpage von Expect:

" erwarten [[-opts] pat1 body1] ... [-opts] patn [bodyn]

wartet, bis eines der Muster mit der Ausgabe eines erstellten Prozesses übereinstimmt, ein bestimmter Zeitraum verstrichen ist oder ein Dateiende zu sehen ist. Wenn der letzte Körper leer ist, kann er weggelassen werden.

Muster aus dem neuesten Befehl 'sleep_before' werden implizit vor allen anderen Mustern verwendet. Muster aus dem neuesten Befehl 'erwartet_after' werden implizit nach allen anderen Mustern verwendet.

Wenn die Argumente für die gesamte Expect-Anweisung mehr als eine Zeile erfordern, können alle Argumente in eine "gespannt" werden, um zu vermeiden, dass jede Zeile mit einem Backslash beendet wird. In diesem Fall treten die üblichen Tcl-Substitutionen trotz der geschweiften Klammern auf.

Wenn ein Muster das Schlüsselwort eof ist, wird der entsprechende Hauptteil am Dateiende ausgeführt. Wenn ein Muster das Schlüsselwort-Timeout ist, wird der entsprechende Textkörper nach dem Timeout ausgeführt. Wenn kein Timeout-Schlüsselwort verwendet wird, wird bei Timeout eine implizite Null-Aktion ausgeführt. Die voreingestellte Timeout-Zeit beträgt 10 Sekunden, kann aber mit dem Befehl "set timeout 30" auf beispielsweise 30 eingestellt werden. Ein unendlicher Timeout kann mit dem Wert -1 bezeichnet werden. Wenn ein Muster das Schlüsselwort default ist, wird der entsprechende Body entweder nach einer Zeitüberschreitung oder nach einem Dateiende ausgeführt.

Wenn ein Muster passt, wird der entsprechende Body ausgeführt. Expect gibt das Ergebnis des Texts zurück (oder die leere Zeichenfolge, wenn kein Muster gefunden wurde). Falls mehrere Muster übereinstimmen, wird das zuerst erscheinende verwendet, um einen Körper auszuwählen. ... "

@DerfK hat Ihre Frage beantwortet. Ich würde jedoch Ihr Skript für die Wartung umgestalten:

#!/bin/bash
export HOST="localhost"
export USER="myuname"
export PASS="mypassword"

script=<<'END_OF_SCRIPT'
    set timeout 120
    spawn ssh $env(USER)@$env(HOST)
    expect "password:"
    send "$env(PASS)\\r"
    expect "\\$"
    send "ls\\r"
    expect -re "$env(USER).*"
    send "logout"
    expect eof
END_OF_SCRIPT

VAR=$(expect -c "$script")

echo "==============="
echo "$VAR"