1

我正在从 unix 服务器执行以下行:

expect -c 'spawn ssh otherHost chown -R user:group /usr ; expect password: ; send 123456\n ; interact ;'

我得到返回值 0、一个空的 stderr 和一个显示/usr/... Not owner, /usr/... Not Owner ...

如果我单独执行命令行ssh otherHost chown -R user:group /usr,则此消息会适当地返回,返回值 !=0 和错误流中的错误消息。

我需要以编程方式知道是否有错误,并且期望(我需要避免传递密码)不允许我这样做。(一个好主意是使用 expect 创建 sshkey,然后正常 ssh 到服务器 - 但我需要服务器在它们之间设置密码)。

无论如何,我怎样才能找出使用期望时发生的错误?

4

1 回答 1

0

我习惯于在脚本中编写所有期望的东西。这有助于调试并增加可读性。

在 Expect 中,您总是可以为每个期望添加一个“超时”来处理异常。当期望模式不匹配时,您可以放一些消息来告知情况。以 ssh 为例:

spawn ssh user@192.168.1.1
expect {
        "Password:"     {send "user123\n"; exp_continue}
        timeout         {send_user "connection fail\n"; exit}
        -ex "$"
}

当没有任何模式匹配时,Expect 将运行该timeout块并显示“连接失败”。

如果我是你,我会将复杂的 ssh 命令拆分为许多简单的命令。即首先ssh到服务器,处理登录过程,然后做chown的东西。该脚本如下所示:

# login
spawn ssh user@192.168.1.1
expect {
        -ex "(yes/no)?" {send "yes\n"; exp_continue}
        "Password:"     {send "user123\n"; exp_continue}
        timeout         {send_user "connection fail\n"; exit}
        -ex "#"
}

# do chown
send "chown -R user /usr\n"
expect {
        "No such file or directory" {send_user "No such file or directory\n"; exp_continue}
        "Operation not permitted" {send_user "Operation not permitted\n"; exp_continue}
        "invalid user" {send_user "Invalid user name\n"; exp_continue}
        -ex "$"
}

请记住,在大多数情况下,Expect 对命令是否成功一无所知。脚本必须通过期望输出字符串来检查自身并处理每种情况。

对于您的情况,我认为有一种简单的方法可以通过 $ 的值检查命令?如果您将原始命令分成小块。

# after ssh login, do chown
send "chown -R user /usr\n"
expect -ex "$"
send "echo rv: $?\n"
expect {
        "rv: 0" {send_user "command successed\n"}
        timeout {send_user "command failed: $expect_out(buffer)\n"; exit}
}

希望这可以帮助。

于 2012-10-12T09:52:06.313 回答