简体   繁体   English

期望脚本-自动密码

[英]Expect Script - Auto Password

I am trying to make a script which automatically enters the password "root" to copy the ssh-key from A to B. Since ssh-copy does not work on B and also cant be installed i used: 我正在尝试制作一个脚本,该脚本自动输入密码“ root”以将ssh密钥从A复制到B。由于ssh-copy在B上不起作用,因此也无法安装,我使用了:

ssh root@$ip mkdir -p .ssh
cat "~/.ssh/id_rsa.pub" | ssh "root@$ip" 'cat >> .ssh/authorized_keys'

To transfer the key. 转移密钥。 But B delets its storage on reboot. 但是B在重新启动时会删除其存储。 So i have to automate this process. 所以我必须自动化这个过程。 I thought a expect script would be the simplest solution? 我以为期盼脚本将是最简单的解决方案? I am however not very experienced with these. 但是,我对这些不是很经验。

#!/usr/bin/expect
#31.09.2015

set timeout 30

spawn ssh "root@$ip mkdir -p .ssh"
expect "password:"
send "root\r"
expect "(yes/no)? "
send "yes\r"

spawn cat "~/.ssh/id_rsa.pub" | ssh "root@$ip" 'cat >> .ssh/authorized_keys'
expect "password:"
send "root\r"

interact

It seems to works till the first send. 它似乎可以工作到第一次发送。 Then however gets stuck and waits for an input? 然后卡住并等待输入吗? (wrong expect?) (期望不正确?)

This is the part you're having trouble with: 这是您遇到问题的部分:

spawn ssh "root@$ip mkdir -p .ssh"
expect "password:"
send "root\r"
expect "(yes/no)? "
send "yes\r"

After you send the password you're waiting 30 seconds for (yes/no? to appear, but it might not appear if you've connected to that machine before. You want to conditionally expect that y/n prompt: 发送密码后,您需要等待30秒才能看到(yes/no? ,但是如果您之前已连接到该计算机,则可能不会出现。您希望有条件地希望出现y / n提示符:

spawn ssh "root@$ip mkdir -p .ssh"
expect {
    "(yes/no)? " { send "yes\r"; exp_continue }
    "password:"  { send "root\r" }
}
expect eof

That form of the expect command allows you to look for multiple strings simultaneously. 这种形式的Expect命令允许您同时查找多个字符串。 If the first one seen is "(yes/no)? ", then send "yes" and continue with this expect command. 如果第一个看到的是“(yes / no)?”,则发送“ yes”并继续执行此Expect命令。 When you see "password:", send the password and let the expect command end. 当您看到“密码:”时,发送密码,并让Expect命令结束。

You might want to change the second spawn command so a shell can handle the pipeline. 您可能需要更改第二个spawn命令,以便外壳程序可以处理管道。

set cmd [format {cat "~/.ssh/id_rsa.pub" | ssh "root@%s" 'cat >> .ssh/authorized_keys'} $ip]
spawn sh -c $cmd

spawn dose not handle input redirection the way you want it to. spawn不会按照您希望的方式处理输入重定向。 The easiest solution is to create a separate shell script that will do the copying and let expect only handle the password prompt. 最简单的解决方案是创建一个单独的shell脚本,该脚本将执行复制操作,并expect仅处理密码提示。

This is what works for me: 这对我有效:

cat copykey.sh : cat copykey.sh

#!/bin/bash
ssh user@host "cat >> .ssh/authorized_keys" < ~/.ssh/id_rsa.pub

cat copykey.expect : cat copykey.expect

#!/usr/bin/expect -f
set timeout 30

spawn ssh user@host mkdir -p .ssh
expect "password:"
send "password\n"
expect "$ "

spawn ~/copykey.sh 
expect "password:"
send "password\n"
expect "$ "

Need to give ip,username,password as command line argument(Remotelogin.exp) 需要给ip,用户名,密码作为命令行参数(Remotelogin.exp)

    #!/usr/bin/expect
    set ip [lindex $argv 0]
    set user [lindex $argv 1]
    set password [lindex $argv 2]
    spawn ssh $user@$ip
    expect {
    "(yes/no)?" {

                  send "yes\r"

                  expect "password:"

                  send "$password\r"

                }

    "password:" {
                   send "$password\r"
                }
           }

` `

Example: ./Remotelogin.exp 示例:./ Remotelogin.exp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM