Unix:使用expect不会';我们不能保存标准

Unix:使用expect不会';我们不能保存标准,unix,expect,file-descriptor,Unix,Expect,File Descriptor,我正在从unix服务器执行以下操作: expect -c 'spawn ssh otherHost chown -R user:group /usr ; expect password: ; send 123456\n ; interact ;' 我得到的是返回值0,一个空的stderr和一个stdout,表示/usr/。。。不是所有者,/usr/。。。不是所有者.. 如果我单独执行命令行ssh otherHost chown-R user:group/usr,则此消息将以返回值正确返回=0和

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

expect -c 'spawn ssh otherHost chown -R user:group /usr ; expect password: ; send 123456\n ; interact ;'
我得到的是返回值0,一个空的stderr和一个stdout,表示
/usr/。。。不是所有者,/usr/。。。不是所有者..

如果我单独执行命令行
ssh otherHost chown-R user:group/usr
,则此消息将以返回值正确返回=0和错误流中的错误消息

我需要通过编程知道是否有错误,expect(我需要避免传递密码)不允许我这样做。(一个好主意是使用expect创建sshkeys,然后使用ssh正常连接到服务器——但我需要服务器之间有密码)


无论如何,我怎样才能发现使用expect时发生的错误?

我习惯于在脚本中编写所有expect内容。这有助于调试并增加可读性

在Expect中,您始终可以为每个Expect处理异常添加一个“超时”。当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将运行
超时
块并显示“连接失败”

如果我是你,我会将复杂的ssh命令拆分为许多简单的命令。i、 首先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}
}
希望这有帮助