Αυτοματισμός SSH με το expect

Υπάρχουν μερικά εργαλεία που παλιά τα χρησιμοποιούσαμε πολύ, αλλά έχουν ξεχαστεί με τα χρόνια. Ένα από αυτά είναι το expect. Με το expect μπορούμε να αυτοματοποιήσουμε πράγματα καθώς και να κάνουμε αυτόματο έλεγχο προγραμμάτων.

Εισαγωγή

Με τα σενάρια του κελύφους εύκολα μπορούν να αυτοματοποιηθούν καθημερινές εργασίες και αντί να γράφουμε ένα κατεβατό από εντολές μπορεί κάποιος να φτιάξει τις δικές του εντολές.

Μετά που έμαθες για αυτά είτε από εδώ και εδώ, είτε από κάποιο βιβλίο είτε από την σειρά μαθημάτων του @billniakas που θα τα βρεις εδώ (διάβασε τα όλα) έχεις ενθουσιαστεί

Σύντομα όμως βρίσκεις πως κάποια πράγματα δεν μπορούν να αυτοματοποιηθούν. Για παράδειγμα μια σύνδεση ssh. Το ssh συχνά θέλει να δώσεις τον κωδικό του χρήστη. Επίσης συχνά θέλεις να δώσεις κάποιες εντολές μετά που θα κάνεις την σύνδεση. Εδώ δεν μας βοηθάει το bash. Ευτυχώς υπάρχει ένα παλιό καλά κρυμμένο μυστικό στα αποθετήρια που μπορεί να μας βοηθήσει. Το λένε expect.

Αυτοματισμός του SSH με το expect

Το expect συνήθως δεν θα το έχουμε εγκατεστημένο και θα πρέπει να το εγκαταστήσουμε. Μετά θα φτιάξουμε το πρώτο μας script και θα το κάνουμε εκτελέσιμο. Δες εδώ για το πως θα το κάνουμε αυτό και που θα βάλουμε το αρχείο.

Ας φτιάξουμε το πρώτο μας script

#!/usr/bin/expect -f

set timeout 60
set my_pass "arn@k1-aspr0+px"

spawn ssh arnaki@stani.com

expect "Password :" 
send $my_pass
send "\r"   

expect "$"
send "cd /var/discourse/r" 

interact

Η πρώτη γραμμή είναι το shebag και λέει στο σύστημα πως είναι ένα σενάριο του expect μετά θέτουμε κάποιες μεταβλητές για ευκολία.

Η εντολή spawn θα ξεκινήσει την εντολή που ακολουθεί μετά. Θα κάνει σύνδεση στον υπολογιστή stani.com σαν τον χρήστη arnaki. Μετά θα περιμένει υπομονετικά (όσο λέει το timeout) να δει την λέξη Password. Η γραμμή αυτή θα μπορούσε να είναι και σαν

 expect "*ssword: "
 expect "*: "
 expect ":"

δηλαδή μπορεί να έχω κανονικές εκφράσεις (regular exressions) ή ακόμα και απλά να περιμένω τον χαρακτήρα :.

Μετά η εντολή send θα στείλει χαρακτήρες σαν να τους είχαμε γράψει στο πληκτρολόγιο. Θα γράφαμε το password μας κανονικά και μετά θα πατάγαμε το πλήκτρο ENTER που εδώ το γράφουμε ώς \r.

Τέλος η εντολή interact μας δίνει πίσω τον έλεγχο.

Στο script βάλαμε μέσα τον κωδικό. Αυτό δεν είναι ότι καλύτερο και ευτυχώς με το ssh μπορούμε να κάνουμε σύνδεση χωρίς τον κωδικό, αλλά αν δεν το έχουμε έτσι θα μπορούσαμε να δίναμε τον κωδικό σαν όρισμα. Κάνουμε μια αλλαγή

set my_pass [lindex $argv 0]

Ένα ποιο πολύπλοκο πρόγραμμα

Ας κάνουμε το πρόγραμμα λίγο ποιο πολύπλοκο.

#!/usr/bin/expect -f

set timeout 9
set username [lindex $argv 0]
set password [lindex $argv 1]
set hostname [lindex $argv 2]

if {[llength $argv] == 0} {
  send_user "Usage: scriptname username password hostname\n"
  exit 1
}

spawn ssh $username@$hostname

expect {
  timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
  eof { send_user "\nSSH failure for $hostname\n"; exit 1 }
  "*assword"
}

send "$password\r"
expect {
  timeout { send_user "\nLogin failed. Password incorrect.\n"; exit 1}
  "*\$ "
}

send_user "\nPassword is correct\n"
send "exit\r"
close

Το καινούργιο εδώ είναι η εντολή send_user που τυπώνει κάποιο κείμενο, και η εντολή close που κλείνει την σύνδεση. Έχει βέβαια και άλλα πράγματα, αλλά πρέπει να ξέρεις TCL και θα μεγαλώσει πολύ το άρθρο. Στην πράξη αυτά αρκούν και είναι εύκολο να καταλάβεις τι συμβαίνει.

Τι είναι αυτή η TCL

H TCL είναι μια γλώσσα προγραμματισμού που βγήκε το μακρινό 1988. Σήμερα είναι σχετικά άγνωστη, αλλά θα μπορούσε, αν η SUN δεν είχε αλλάξει γνώμη να είχε την θέση της JavaScript.

H TCL μοιάζει με την γλώσσα lua. Είναι μια γλώσσα με την οποία μπορείς να προσθέσεις δυνατότητες προγραμματισμού σε κάποιο πρόγραμμα. Σήμερα θα το κάνεις αυτό με την Lua αλλά υπάρχουν πολλά προγράμματα που ακόμα χρησιμοποιούν την TCL και παραμένει μια χρήσιμη γλώσσα.

Σε αντίθεση όμως με την Lua η TCL είναι και μια αυτόνομη γλώσσα κελύφους. To expect που γράφτηκε το 1990 πέρνει το κέλυφος και προσθέτει κάποιες εντολές.

Μια άλλη κληρονομία της TCL που θα την βρείς σχεδόν σε όλλες τις scripting γλώσσες, συχνά ενδωματομένο, είναι η βιβλιοθήκη Tk Με αυτήν φτιάχνεις γραφικά GUI πολύ ευκολότερα απο άλλες μεθόδους και είναι και cross plattform. Δυστυχώς δεν είναι πάντα όμορφα.

3 Likes

Καλησπερα σας.
Αντιμετωπιζω το εξης προβλημα.
Παιρνω το παρακατω μηνυμα οταν εκτελω ενα bash script παρομοιο με το πρωτο που υπαρχει στο αρθρο και παιρνω:

ssh_pc_labs.sh: 6: ssh_pc_labs.sh: spawn: not found
couldn't read file ":": no such file or directory
ssh_pc_labs.sh: 9: ssh_pc_labs.sh: send: not found
ssh_pc_labs.sh: 10: ssh_pc_labs.sh: send: not found
ssh_pc_labs.sh: 12: ssh_pc_labs.sh: interact: not found

Αλλα εχω εγκαταστησει κανονικα την expect, αφου πρωτα εγκατεστηκα το Linuxbrew.
Με την εντολη ’ brew install expect’ παιρνω το μηνυμα: ‘Warning: expect 5.45.4 is already installed and up-to-date’ που σημαινει οτι εχει εγκατασταθει κανονικα η expect.

Δεν είναι script γραμμένο σε bash. Είναι script γραμμένο σε expect που είναι άλλο πράγμα και άλλη γλώσσα.

Η πρώτη γραμμή

#!/usr/bin/expect -f

πρέπει να δείχνει στο εκτελέσιμο αρχείο του expect αντί για το bash που δείχνει στα “απλά” scripts.

Θα πρέπει να κάνεις το αρχείο εκτελέσιμο και να το τρέξεις με το όνομα του. Δες εδώ.

2 Likes

Εχετε απολυτο δικιο, δεν το γνωριζα. Μολις το διορθωσα και τρεχει κανονικα.
Σας ευχαριστω πολυ!

1 Like