2
\$\begingroup\$

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
```
\$\endgroup\$
2
\$\begingroup\$

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
      lassign $argv user server
      
      which is arguably a bit less readable, but is only one command.
  • 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 remove set rc 0 and exit $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 block

    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 }
    }
    

    If $prompt is seen, then that expect command ends, and the script continues with send

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.