期望脚本用于远程ssh登录和执行命令

时间:2014-03-03 13:03:36

标签: ssh expect

我正在使用以下expect脚本远程ssh登录到raspberry pi并执行命令

#!/usr/bin/expect
set timeout 60
spawn ssh [lindex $argv 1]@[lindex $argv 0]
expect "yes/no" {
    send "yes\r"
    expect "*?assword" { send "[lindex $argv 2]\r" }
    } "*?assword" { send "[lindex $argv 2]\r" }
expect "pi@raspberrypi ~ $ " {
    send "ls -la\r"
    }
interact

问题是这个脚本能够登录到raspberry但是当执行“ls -la”命令行时没有任何反应。任何人都可以帮我解决这个脚本吗?我在哪里弄错了?

好的,如果我把

  

exp_internal 1

在我的脚本中

行我在匹配失败的地方得到以下输出

  

期待:确实是::\ r \ nLinux raspberrypi 3.10.24+#614预览12月19日20:38:42 GMT 2013 armv6l \ r \ n \ r \ n Debian GNU / Linux系统附带的程序是免费的软件; \ r \ n每个程序的确切分发术语在/usr/share/doc/*/copyright.\r\n\r.nDebian中的\ r \ n个人文件中描述.GNU / Linux绝对不提供保证,在适用法律的适用范围内。\ r \ n最后登录:2014年3月3日19:00:11从192.168.1.200 \ r \ n \ r \ n \ u001b] 0; pi @ raspberrypi:〜\ u0007 \ u001b [01; 32mpi @ raspberrypi \ u001b [00m \ u001b [01; 34m~ $ \ u001b [00m“(spawn_id exp6)匹配glob模式”* pi @ raspberrypi~ $ *“?无

这种匹配不应该是真的吗?

3 个答案:

答案 0 :(得分:9)

在密码和真实性检查完成后,您应该使用exp_continue重新输入您的expect循环,请尝试以下操作:

#!/usr/bin/expect

set prompt "pi@raspberrypi ~ $ "
spawn ssh [lindex $argv 1]@[lindex $argv 0]                                                         

set timeout 5
expect {
    timeout {
        puts "Connection timed out"
        exit 1
    }

    "yes/no" {
        send "yes\r"
        exp_continue
    }

    "assword:" {
        send -- "[lindex $argv 2]\r"
        exp_continue
    }

    "$prompt" {
        send "ls -la\r"
    }
}

这是摘自“探索期待”中关于Don Libes的exp_continue:

  

当作为expect动作执行时,命令exp_continue导致控制在当前expect命令内继续。期望继续尝试匹配模式,但从上一场比赛后的中断位置。期望有效地重复其搜索,就像它再次被调用一样。

答案 1 :(得分:3)

你可能会看一下......它需要一个包含在文件中的命令列表,并通过交互式登录和远程主机上的命令执行它们。 在远程计算机上一次一个地执行它们。您可以打开日志记录 如果你想捕获输出,你需要调整它来处理你的 计算机(或其他设备)提示:


    #!/usr/bin/expect
    #
    # Read a list of commands and execute them on remote host
    #
    # WA2IAC 3/9/2015
    #

    spawn ssh -l username target_host
    expect "ord\\: "
    send "your_password\r"
    set handle [ open commandfile.txt r ]
    while { ! [eof $handle] } {
        gets $handle buf
        expect "\\$"
        send "$buf\r"
        }
    interact

你可以通过设置超时和处理可能出错的事情来充实这一点(参见上面的代码片段)。删除“interact”语句以使脚本在完成时退出(您可以使用shell循环来执行此操作) 主机/设备)。

我用它来发送命令路由器来更新静态路由,但它有许多其他用途。我从这里得到了它:http://wa2iac.com/wiki/index.php?title=Expect_remote_commands

答案 2 :(得分:0)

我还建议您在使用expect命令时确保使用上一个send命令输出的最后一个字符串模式。我告诉你这是因为Expect的输出保存在缓冲区中,而缓冲区只能保存这么多数据。我有一段时间没有找到我的expect -re {}命令未被正确拾取的原因,我一直在努力解决这个问题,我期待前一个发送命令输出的前几个String模式。我应该一直在寻找最后的String模式,因为这个String模式肯定是在Expect的缓冲区中,并且第一个字符串已被删除,因为缓冲区只能容纳如此多的数据。我发送命令的输出有点长。