我有任意数量的服务器具有相同的用户/密码组合。我想编写一个脚本(我调用一次),以便
ssh-copy-id user@myserver
为每个服务器调用。由于它们都具有相同的用户/密码,这应该很容易,但ssh-copy-id
每次都要求我单独输入密码,这违背了我的脚本的目的。没有输入密码的选项,即ssh-copy-id -p mypassword user@myserver
。
ssh-copy-id
我如何编写一个脚本,在要求输入密码时自动填写密码字段?
答案1
看一眼密码. 将您的密码放在文本文件中,然后执行以下操作:
$ sshpass -f password.txt ssh-copy-id user@yourserver
答案2
您可以使用 expect 来监听密码提示并发送您的密码:
#!/usr/bin/expect -f
spawn ssh-copy-id $argv
expect "password:"
send "YOUR_PASSWORD\n"
expect eof
保存脚本,使其可执行,然后按如下方式调用它:./login.expect user@myserver
答案3
quanta 的答案非常好,但它要求您将密码放在文本文件中。
从sshpass
手册页中:
如果没有给出选项,sshpass 将从标准输入读取密码。
因此,您可以做的是在脚本期间捕获一次密码,将其存储在变量中,回显密码并将其作为输入传送到 sshpass。
我一直这样做,效果很好。例如:
echo "Please insert the password used for ssh login on remote machine:"
read -r USERPASS
for TARGETIP in $@; do
echo "$USERPASS" | sshpass ssh-copy-id -f -i $KEYLOCATION "$USER"@"$TARGETIP"
done
答案4
这是 ssh-copy-id 的一个问题;每次运行它时,它还会添加一个密钥。如果您要自动执行此过程,您的 authorized_keys 文件很快就会因重复的密钥而变得杂乱无章。这里有一个 Python 程序可以避免这两个问题。它从控制服务器运行,并将一个远程服务器中的密钥放入另一个远程服务器。
import subprocess
def Remote(cmd,IP):
cmd = '''ssh root@%s '''%(IP)+cmd
lines = subprocess.check_output(cmd.split())
return '\n'.join(lines)
source = '123.456.78.90'
target = '239.234.654.123'
getkey = 'cat /root/.ssh/id_rsa.pub'
getauth = 'cat /root/.ssh/authorized_keys'
sourcekey = Remote(getkey, source).replace('\n','').strip()
authkeys = Remote(getauth, target).replace('\n','').strip()
if sourcekey not in authkeys:
keycmd=''' echo "%s" >>/root/.ssh/authorized_keys;
chmod 600 /root/.ssh/authorized_keys '''%(sourcekey) # A compound shell statement
print 'Installed key', Remote(keycmd,target)
else: print 'Does not need key'