Apr 172012
 

Nel mio lavoro non ho usato molte volte “Expect“, ma per fare alcuni compiti ho imparato ad usarlo e devo dire che per completare alcune attività questo programma può aiutare molto ed essere una valida alternativa a soluzioni più complesse , come un programma completo in python, php o il vostro programma di scripting preferito.

Ma prima una descrizione di expect presa dalla sua pagina man:

Expect è un programma che “parla” con altri programmi interattivi in base ad uno script. Dopo lo script, Expect sa cosa aspettarsi da un programma e quale dovrebbe essere la risposta corretta. Un linguaggio interpretato fornisce ramificazionei ad alto livello e strutture di controllo per dirigere il dialogo. Inoltre, l’utente può assumere il controllo e interagire direttamente quando desiderato, poi restituire il controllo allo script.

In questo articolo vi mostrerò 2 esempi su come usarlo, per connettersi a un server remoto via ssh e dare un comando, per cambiare la password di un utente con il comando passwd.




In generale, Expect è utile per l’esecuzione di qualsiasi programma che richiede l’interazione tra il programma e l’utente. Tutto ciò che è necessario è che l’interazione possa essere prevedibile a livello di programmazione.

Expect utilizza Tcl (Tool Command Language). Tcl fornisce il controllo per il flusso (ad esempio, if, for, break), la valutazione delle espressioni e diverse altre funzioni come la ricorsione, definizione delle procedure, Per conoscere esattamente tutti i comandi supportati da Expect controllare la sua pagina man e quella di TCL

Uso Base

Expect legge un cmdfile per ottenere un elenco di comandi da eseguire. Expect può anche essere invocato implicitamente sui sistemi che supportano la notazione #! contrassegnando lo script come eseguibile, e mettendo come prima linea nello script:

#!/usr/local/bin/expect -f

Nei miei esempi userò questo metodo per creare uno script expect, metterò commenti per descrivere come le azioni/comandi sono implementati.

1 – Accesso con ssh a un server remoto e dare 1 comando lì con Expect

Create un nuovo file, per esempio ssh.exp, e incollare il seguente contenuto, dopo di che rendetelo eseguibile con il comando

 chmod +x ssh.exp

ssh.exp:

!/usr/bin/expect -f
#From Linuxaria.com the script is licensed under GNU GPL version 2.0 or above 
#Expect script per dare username, password ip/porta
# di un server ssh remoto ed eseguire un comando
# Questo script ha bisogno di 5 argomenti:
# username = Username unix sulla macchina remota
# password = password per l'utente fornito
# server =indirizzo ip o hostname del server
# port = porta SSH su server remoto, normalmente è la 22
# program = percorso completo del comando da eseguire
 
#Come prima cosa verifichiamo che ci siano 5 argomenti;
if {[llength $argv] != 5} {
 
# Diamo un messaggio così l'utente conosce la sintassi:
puts "usage: mysshconnection.exp username password server port command"
 
#Ed usciamo con return code = 1
exit 1
}
 
# Adesso configuriamo le varibili expect, notare  [lrange $argv 0 0 =$1, il primo parametro, e così via.
 
set username [lrange $argv 0 0]
set password [lrange $argv 1 1]
set server [lrange $argv 2 2]
set port [lrange $argv 3 3]
set program [lrange $argv 4 4]
 
#Il valore di timeout deve essere un numero intero di secondi. Normalmente timeout non è negativo, ma il caso particolare di -1 significa che si 
# aspetterà per sempre
 
set timeout 60
 
# Ora siamo in grado di connetterci al server remoto/porat con il nostro username e password, il comando spawn viene utilizzato per 
# eseguire un altro processo:
spawn ssh -p $port $username@$server $program
match_max 100000
 
# Adesso ci aspettiamo di avere una richiesta di password
expect "*?assword:*"
 
# E mandiamo la nostra password
send -- "$password\r"
 
#  Mandiamo una blank like (\r) per essere sicuri di tornare alla cli
send -- "\r"
 
#Abbiamo eseguito il nostro comando e ora ci aspettiamo che il server remoto chiuda la connessione:
expect eof

Perfetto ora è possibile dare dal vostro terminale:

./ssh.exp root mysecretpw linuxaria.com 22 halt

E chiudere questo blog ;)

2 – Usare expect per cambiare la password di un utente

Potrebbe essere utile per cambiare automaticamente (senza interazione) la password per un determinato nome utente, possiamo fare questo con aspettano
NOTA: questo script deve essere eseguito come root.

passwd.exp

#!/usr/bin/expect -f
# In questo script abbiamo bisogno di 2 argomenti username e password
if {[llength $argv] != 2} {
 
# Diamo un messaggio così l'utente conosce la sintassi
puts "usage: /passwd.exp username password "
 
#Usciamo con return code = 1
exit 1
}
 
set username [lindex $argv 0]
set newpass [lindex $argv 1]
spawn passwd $username
 
expect "?assword:"
send \"$newpass\r\"
expect "?assword:"
send \"$newpass\r\"
expect eof

Ma non dimenticate che è possibile utilizzare aspettare anche all’interno di uno script bash, per esempio il nostro passwd.exp potrebbe diventare un passwd.sh:

#!/bin/bash
 
die () {
    echo >&2 "$@"
    exit 1
}
 
[ "$#" -eq 2 ] || die "2 argomenti richiesti, $# forniti"
 
username=$1;
newpass=$2;
export HISTIGNORE="expect*";
 
expect -c "
        spawn passwd $username
        expect "?assword:"
        send \"$newpass\r\"
        expect "?assword:"
        send \"$newpass\r\"
        expect eof"
 
export HISTIGNORE="";

Questo è utile quando si ha a che fare con programmi più lunghi e si preferisce utilizzare come linguaggio la bash.

Conclusioni

Questi sono 2 buoni esempi su come può essere flessibile ed utile Expect per automatizzare molte piccole (e grandi cose) da un semplice comando dato a un server remoto fino alla generazione completa di un username/password su 1 (o più) sistemi unix.

Popular Posts:

flattr this!

  5 Responses to “2 Esempi pratici di Expect sulla Linux CLI”

  1. Complimenti!!!! grazie per questo interessantissimo articolo!

  2. Oh…non sai da quanto tempo attendevo un articolo su questo argomento. Finalmente potrò sviluppare un automatismo per creare gli utenti postgres dai miei software.

    Grazie 1 milione!!!

  3. Excellent examples of how to automation CLI in expect. Have you looked at expect-lite, which is even easier to do CLI automation?
    http://expect-lite.sf.net/

  4. You’re missing the # in the shebang in your first script.

 Leave a Reply

(required)

(required)


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>