无法通过expect SSH SSH bash命令的脚本

时间:2017-01-25 17:54:33

标签: linux bash ssh expect

我试图将一组命令推送到多个远程主机。我可以单独使用以下内容:
ssh user@remoteHost "bash -s" <./commands.sh
我可以把它放到一个循环中,但后来我很难输入密码n次。禁用SSH配置文件中的密码提示对我来说不是一个选项。 我试图在循环中使用expect,但我无法让它工作。

#!/bin/bash  
HOSTS="host1 host2"  
read -sp "Password: " PASSWORD  
for HOST in $HOSTS; do  
    expect -c "  
    spawn /usr/bin/ssh user@$HOST "bash -s" <./commands.sh  
    expect_before {
        "*yes/no*" {send "yes"\r;exp_continue}}
    expect {
        "*Password*" {send $PASSWORD\r;interact}}
    exit"
done

我收到以下错误:

spawn /usr/bin/ssh root@host1 bash  
expect: invalid option -- 's'  
usage: expect [-div] [-c cmds] [[-f] cmdfile] [args]  
spawn /usr/bin/ssh root@host2 bash  
expect: invalid option -- 's'  
usage: expect [-div] [-c cmds] [[-f] cmdfile] [args]  

有什么想法吗?似乎期望试图解释bash命令。我不确定如何制止这一点。

2 个答案:

答案 0 :(得分:1)

解决方案:
更换
sprintf

spawn /usr/bin/ssh user@$HOST "bash -s" <./commands.sh
最终守则:

spawn sh -c {ssh root@$HOST 'bash -ls' < /tmp/commands.sh}

答案 1 :(得分:0)

我建议:

#!/bin/bash  
hosts=(host1 host2)
read -sp "Password: " password  
for host in "${hosts[@]}"; do  
    env h="$host" p="$password" expect <<'END_EXPECT'
        spawn sh -c "/usr/bin/ssh user@$env(h) 'bash -s' <./commands.sh"
        expect {
            "*yes/no*"   {send "yes\r"; exp_continue}
            "*Password*" {send "$env(p)\r"}
        }
        interact
END_EXPECT
done

注释

  • 使用小写变量名:保留shell的大写varnames
  • 使用带引号的heredoc来包含期望代码
    • 允许你在期望中使用单引号和双引号,而不必担心在shell中引用地狱
  • 使用env传递shell变量以期望通过环境
  • 简化您的期望陈述

使用

的危险
expect -c " ...; expect "*Password*" ..."

是内部双引号与外引号匹配,并由shell删除。这使得*Password*成为一个裸的glob,shell可以根据当前目录中的文件和shell设置进行扩展。例如,创建一个名为&#34;密码&#34;的文件。 (有空间),你会得到一个 错误。