2016-08-05 99 views
0

我试图做一个expect脚本与试图连接ssh并查看是否有可能(良好的密码和可达)的循环。我试图把结果放入一个变量中,但只记录标准输出的结尾,而不是所有的标准输出。我怎么办?期待和Bash脚本

result=$(
(/usr/bin/expect << EOF 
    spawn ssh [email protected]$ip -o StrictHostKeyChecking=no 
    set timeout 2 
    expect ":" 
    send -- "$password\r" 
    expect ">" 
    send -- "show clock\r" 
    expect ">" 
EOF 
) 2>&1) 

谢谢。

+0

你能澄清你的意思吗(re:“只有stdout的结尾被记录,而不是所有的stdout”)?什么exac tly在你的输出中,你期望*在你的输出中有什么,你如何检查? (通常,人们会使用'echo $ result'来模糊实际内容)。 –

+0

如果我写: echo $ result 只显示最后一行的一部分。 – 77140B

+0

'declare -p result'通常是查看变量实际内容的更好方法 - echo有很多方法可以搞砸。如果有隐藏字符混淆的可能性,'printf'%q \ n'“$ result”'同样是一个改进。但是,如果您*要*使用'echo',至少应避免忽略引号:'echo“$ result”',而不是'echo $ result'。 –

回答

3

如果你想使用自动发送ssh命令到另一台服务器:

  • 生成一个ssh键,而是采用密码:

    ssh-keygen -t rsa -b 2048 
    
  • 它复制到服务器:

    ssh-copy-id [email protected] 
    

现在你不需要担心密码。 ssh密钥充当密码,并且一般都是更安全。请参阅这些(SSH login without password,Why is using SSH key more secure than using passwords?)以获取有关ssh密钥的更多信息。

然后你可以使用这个命令 - 不需要expect,因为你不会被要求输入密码。它会使用您的ssh密钥。矿区位于~/.ssh/id_rsa。所以:

ssh [email protected] -i ~/.ssh/id_rsa "show clock;" 
  • -i代表的身份文件,即你的ssh密钥文件。

会向SSH服务器发送命令。

现在总共:

ssh-keygen -t rsa -b 2048 
ssh-copy-id [email protected] 
ssh [email protected] -i ~/.ssh/id_rsa "show clock;" 

三个命令,并且你做到了!

+1

由于'〜/ .ssh/id_rsa'是(a?)默认值,所以不需要'-i'参数。 'ssh id @ server show clock'。 – chepner

+0

@chepner可以工作,但如果你像我一样,你有许多不同服务器的'ssh'键。我已经包含'-i'标志,所以很明显你也可以选择在那个命令中使用哪个'ssh'文件。 –

0

调用从shell脚本expectscript:

expect "/copySSHKey.exp <machine> <password> </.ssh/id_rsa.pub path>" 

Expect脚本:

#!/usr/bin/expect -f 

set machine [lrange $argv 0 0] 
set ip [lrange $argv 1 1] 
set pass [lrange $argv 2 2] 
set path [lrange $argv 3 3] 

set timeout -1 
spawn ssh-keygen -R ${machine} 
spawn ssh-copy-id -i ${path} [email protected]${machine} 

match_max 100000 

expect { 

    sleep 10 

    "password" { 
      send -- "$pass\r" 
      send -- "\r" 
      sleep 1 
      send_user " SSH key copied to $machine\n" 
    } 

    "$machine's" { 
      send_user " SSH key copied to $machine\n" 
    } 

    "password:*" { 
      send -- "$pass\r" 
      send -- "\r" 
      sleep 1 
      send_user " SSH key copied to $machine\n" 
    } 

    "machine" { 
      sleep 1 
      send_user " SSH key copied to $machine\n" 
    } 
} 

interact 
-1

尝试使用双引号(“)来捕获子shell的输出也许你正在失去,因为分析的数据。问题:

result="$(...)" 
+1

实际上不需要赋值 - 这是禁用字符串拆分和glob扩展的上下文。你可以很容易地测试它:'var = $(printf'%s \ n'hello cruel world'*'); declare -p var',并注意换行符仍然存在(没有用空格替换,因为如果使用默认的IFS进行了字符串分割,它们将会是空格),星号也是如此(不会被替换为当前工作目录)。 –