迭代 ssh-copy-id 命令以在多个主机上复制

Posted

技术标签:

【中文标题】迭代 ssh-copy-id 命令以在多个主机上复制【英文标题】:iterating ssh-copy-id command to copy on multiple hosts 【发布时间】:2016-02-03 12:58:15 【问题描述】:

我正在尝试将公钥复制到名为“hostsfile”的文件中的多个主机。 我正在编写一个脚本,允许我在设置开发环境时这样做,并且我可能最终会一遍又一遍地这样做。 谷歌搜索我已经能够使用 ssh-copy-id 命令插入公钥,并且能够为一台主机自动化它。 然而,代码需要微调以通过主机文件中的每个主机......不幸的是它完成了第一个条目然后退出: 下面是代码......提前感谢任何帮助......

#!/usr/bin/expect
set timeout 10
set f [open "hostsfile"]
set hosts [split [read $f] "\n"]
close $f

set exp_internal 1
foreach host $hosts 
    spawn ssh-copy-id -i /home/vagrant/.ssh/ansible-use-ssh-key.pub $host
    expect_after eof  exit 0 
    expect "password:"  send "vagrant\r" 
    expect_after eof  exit 0 
    expect "$ "
    
send "exit\r"
expect eof

Glen 这是我用你的 cmets 做的……你能不能给我建议,如果你不介意帮助完整的代码:

#!/usr/bin/expect
set timeout 10
set f [open "hostsfile"]
close $f

set hosts [split [read -nonewline $f] "\n"]

foreach host $hosts 
    spawn ssh-copy-id -i /home/vagrant/.ssh/ansible-use-ssh-key.pub $host
    expect "password:" 
    send "vagrant\r"
    expect eof

puts done

嗨,格伦,它可以按照您的建议使用以下代码。但是,如果密钥已存在于其中一台主机上,则该过程终止。如果远程主机响应密钥已经存在,您能否建议我如何添加 if/else 状态以使其不会中断?提前感谢您的帮助。

下面是解决第一个问题的代码。

#!/usr/bin/expect
set timeout 10
set f [open "hostsfile"]
set hosts [split [read -nonewline $f] "\n"]
close $f


foreach host $hosts 
    spawn ssh-copy-id -i /home/vagrant/.ssh/ansible-use-ssh-key.pub $host
    expect "password:"
    send "vagrant\r"
    expect eof

完成

【问题讨论】:

【参考方案1】:

您已指示expect 在eof 之后退出。不要那样做。

foreach host $hosts 
    spawn ssh-copy-id -i /home/vagrant/.ssh/ansible-use-ssh-key.pub $host
    expect "password:" 
    send "vagrant\r"
    expect eof

puts done

请注意,您的 $hosts 列表的最后一个元素为空。使用read -nonewline读取文件:

set hosts [split [read -nonewline $f] "\n"]

【讨论】:

谢谢格伦,但是我现在收到以下错误:“在执行从“split [read -nonewline $f”中调用的“read -nonewline $f”时找不到名为“file6”的频道] "\n"" 从 "set hosts [split [read -nonewline $f] "\n"]" 中调用(文件 "./ssh-copy_F.sh" 第 6 行) 您的本意是替换当前的拆分读取行,而不是在您关闭文件后添加新行。 好的,我想我发现了错误...我切换了关闭并设置了主机行...但是现在面临另一个问题,如果密钥已经存在于其中一个主机上,则它会终止整个脚本...那么我将如何将其添加到脚本中?提前感谢您的帮助。【参考方案2】:

格伦,我找到了第二个问题的答案……下面是显然对我有用的代码。感谢您的热心帮助并帮助我度过难关。

#!/usr/bin/expect
set timeout 10
set f [open "hostsfile"]
set hosts [split [read -nonewline $f] "\n"]
close $f

foreach host $hosts 
    spawn ssh-copy-id -i /home/vagrant/.ssh/ansible-use-ssh-key.pub $host
    expect 
            "password:" 
                    send "vagrant\r"
                    exp_continue
                
                "already exist on the remote system." 
                    exp_continue
                
    expect eof
        

puts done

【讨论】:

expect eof 更改为 eof

以上是关于迭代 ssh-copy-id 命令以在多个主机上复制的主要内容,如果未能解决你的问题,请参考以下文章

ssh-copy-id命令解析

Linux 命令(210)—— ssh-copy-id 命令

Linux 命令(210)—— ssh-copy-id 命令

ssh-copy-id

shell脚本实现ssh-copy-id批量自动发送公钥到远程主机

利用ssh-copy-id复制公钥到多台服务器