I have written a simple expect script to tell me if a passwordless connection is set up.
#!/usr/bin/expect -f
if {[llength $argv] < 2} {
puts "usage: test-nopass user server"
exit 1
}
set user [lindex $argv 0]
set server [lindex $argv 1]
set pwd_prompt "*assword:"
set prompt "*$ "
set rc 0
log_user 0
spawn ssh $user@$server
expect {
"$pwd_prompt" { exit 1 }
eof { exit 2 }
timeout { exit 3 }
"$prompt" {
send "hostname\r"
expect {
"*$server*" { exit 0 }
eof { exit 4 }
timeout { exit 5 }
}
}
}
log_user 1
exit $rc
```
1 Answer 1
A couple of notes:
expect
is an extension of Tcl, so you can use any Tcl command: http://www.tcl-lang.org/man/tcl8.6/TclCmd/contents.htm- specifically, you could write
which is arguably a bit less readable, but is only one command.lassign $argv user server
- specifically, you could write
You can speed up the timeouts: the default is 10 seconds, and you probably don't want to wait for 20 seconds to get the final exit status:
set timeout 1 ;# in seconds
you never reset the
rc
variable, and the default exit status is zero already, so you can removeset rc 0
andexit $rc
expect is not bash: you don't need to quote all the variables.
you don't need to reset
log_user
just before exiting the script.expect code written in this style can get pretty deeply nested: The last pattern in an
expect
command does not need an action blockexpect { $pwd_prompt { exit 1 } eof { exit 2 } timeout { exit 3 } $prompt } send "hostname\r" expect { *$server* { exit 0 } eof { exit 4 } timeout { exit 5 } }
If
$prompt
is seen, then thatexpect
command ends, and the script continues withsend