Leniork
Leniork

Reputation: 75

How to handle "no such file or directory" in expect script?

I have script that uses #!/usr/bin/expect to connect/disconnect to VPN.
But not all of my PCs configured similarly so VPN command can be at PATH but it also can be not.

My question is: how to handle moment when there is no such command in PATH. Script just stops when he tries to execute command that is not presented in PATH.

Here is script that I'm wrote so far:

#!/usr/bin/expect -d

set timeout -1
spawn vpn status
expect {
    "Disconnected" {
      expect eof
      set timeout -1
      spawn vpn connect <vpnurl>
      expect "Username:"
      send "username\r"
      expect "Password:"
      send "password\r"
      expect eof
    }
    "Connected" {
      expect eof
      set timeout -1
      spawn vpn disconnect
      expect eof
    }
  "*" {
      set timeout -1
      spawn /opt/cisco/anyconnect/bin/vpn status
      expect {
        "Disconnected" {
          expect eof
          set timeout -1
          spawn /opt/cisco/anyconnect/bin/vpn connect <vpnurl>
          expect "Username:"
          send "username\r"
          expect "Password:"
          send "password\r"
          expect eof
        }
        "Connected" {
          expect eof
          set timeout -1
          spawn /opt/cisco/anyconnect/bin/vpn disconnect
          expect eof
        }
      }
    }
}

And error that I receive when command not in PATH:

spawn vpn status
couldn't execute "vpn": no such file or directory
    while executing
"spawn vpn status"

I tried to use which vpn and command -v vpn to check if vpn is here but they just don`t produce any output.

Upvotes: 0

Views: 799

Answers (2)

glenn jackman
glenn jackman

Reputation: 246774

You can do the existence test in expect/tcl before attempting to spawn it:

foreach vpn {vpn /opt/cisco/anyconnect/bin/vpn} {
    set path [auto_execok $vpn]
    if {$path ne "" && [file executable $path]} {
        set vpn_exec $path
        break
    }
}

if {$vpn_exec eq ""} {
    puts stderr "vpn not executable: is it installed?"
    exit 1
}

spawn $vpn_exec status
...

See

Upvotes: 2

Shawn
Shawn

Reputation: 52344

expect is a tcl extension, and tcl has a few options for trapping and handling errors: try and catch. Something along the lines of:

if {[catch {spawn vpn status} msg]} {
    puts "spawn vpn failed: $msg"
    puts "Trying again with absolute path"
    spawn /path/to/vpn status
}

Upvotes: 3

Related Questions