如何在 expect 脚本中处理 "no such file or directory"?

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

我有使用 #!/usr/bin/expect 到 connect/disconnect 到 VPN 的脚本。
但并非我所有的 PC 配置都相似,因此 VPN 命令可以在 PATH 中,但也可以不在。

我的问题是:当PATH中没有这样的命令时如何处理。当他尝试执行 PATH 中未出现的命令时,脚本就会停止。

这是我目前写的脚本:

#!/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
        }
      }
    }
}

当命令不在 PATH 中时我收到的错误:

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

我尝试使用 which vpncommand -v vpn 来检查 vpn 是否在这里,但它们没有产生任何输出。

expect 是一个 tcl 扩展,tcl 有几个用于捕获和处理错误的选项:try and catch。大致如下:

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

您可以在 expect/tcl 中进行存在性测试,然后再尝试生成它:

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