Search code examples
error-handlingexpect

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.


Solution

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