0

我试图弄清楚期望如何工作。AFAIK 期望脚本由“期望”和“发送”语句组成。因此,对于出现在屏幕上的每个适当的“期望”语句,都会调用“发送”语句。命令“interact”也意味着控制权被传回给用户,他能够与终端进行交互。如果我错了,请纠正我。这两个陈述就像一个魅力。

第一个:

#!/usr/bin/expect
spawn ssh -q localhost;

# Handles following message: "Are you sure you want to continue connecting (yes/no)?"
expect "yes";
send "yes\r";
interact;

第二:

#!/usr/bin/expect
spawn ssh -q localhost;

# Handles following message: "pista@localhost's password:" 
expect "assword";
send "password\r";
interact;

我在互联网上发现类似以下代码的内容应该将这两个示例合二为一:

#!/usr/bin/expect
spawn ssh -q localhost "uname -a";
expect {
    "*yes/no*" { send "yes\r" ; exp_continue }
    "*assword:" { send "password\r"; interact }
}

但是此示例在成功登录后立即退出(似乎“交互”在这里不起作用,请参见下面的输出)

[pista@HP-PC .ssh]$ ./fin.exp
spawn ssh -q localhost uname -a
pista@localhost's password: 
Linux HP-PC 3.6.6-1.fc16.x86_64 #1 SMP Mon Nov 5 16:56:43 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
[pista@HP-PC .ssh]$ set | grep SHLV
SHLVL=2

三个问题:

  1. 那些奇怪的期望语法意味着什么,对我唯一可能的解释是,在这个“大”期望中没有强调模式顺序?
  2. 您能否澄清一下 exp_continue 到底在做什么,在我看来就像“goto”语句期望哪个调用了这个?
  3. 为什么交互在这里不工作?

非常感谢

4

1 回答 1

1

1.这种语法意味着你使用连续的expect语句,更容易。例如,如果 SSH 失败,这将尝试 SSH 或 telnet

#!/usr/bin/expect
set remote_server [lrange $argv 0 0]
set timeout 10
spawn ssh -M username@$remote_server
while 1 {
  expect {
    "no)?"      {send "yes\r"}
    "denied" {
                log_file /var/log/expect_msg.log
                send_log "Can't login to $remote_server. Check username and password\n";
                exit 1
             }
    "telnet:" {
                log_file /var/log/expect_msg.log
                send_log "Can't connect to $remote_server via SSH or Telnet. Something went definitely wrong\n";
                exit 2
              }
    "failed" {
                log_file /var/log/expect_msg.log
                send_log "Host $remote_server exists. Check ssh_hosts file\n";
                exit 3
             }
    timeout {
                log_file /var/log/expect_msg.log
                send_log "Timeout problem. Host $remote_server doesn't respond\n";
                exit 4
            }
    "refused" {
                log_file /var/log/expect_msg.log
                send_log "Host $remote_server refused to SSH. That is insecure.\n"
                log_file
                spawn telnet $remote_server
              }
    "sername:" {send "username\r"}
    "assword:" {send "password\r"}
    "#"        {break}
  }
}

2. exp_continue 告诉expect“继续期望”,即继续进行事件处理。如果没有此指令,您的 expect { ... } 块将停止。在上面的示例中,它是以下行:

"#" {break}

首先它从 while 循环中中断,然后在没有 exp_continue 的情况下停止执行 expect { ... } 块并继续执行下一条指令(上面的示例中未显示)。

3.你的代码有错误。我稍微修改了您的代码,以使其正常工作。

#!/usr/bin/expect
spawn ssh -q localhost
expect {
    "*yes/no*" { send "yes\r" ; exp_continue }
    "*assword:" { send "password\r"; exp_continue;}
    "~" {send "uname -a\r"; interact;}
}
于 2012-12-26T12:26:20.243 回答