我有我需要安裝我的公鑰的主機列表。爲此,我編寫了一個ruby腳本,它調用期望腳本並將密碼,主機名和公鑰文件傳遞給它。這個expect文件依次爲每個主機執行ssh-copy-id,通過輸入密碼並回答未知主機密鑰的「yes」。期望腳本凍結從Ruby調用時
預期腳本在命令行運行時絕對正常。但是,當從一個ruby腳本執行時,期望對未知的主機密鑰確認回答「是」:「您確定要繼續連接(是/否)?」。期望腳本只在「是/否」問題被拋出時凍結。
任何幫助將不勝感激。
這裏是我的Ruby腳本:
#!/usr/bin/env ruby -w
hosts=['[email protected]','[email protected]','[email protected]']
password="blahblahblah"
key_file="/home/blah/.ssh/id_rsa.pub"
hosts.each{ |host|
command="expect sshcopy.exp #{host} #{key_file} #{password}"
`#{command}`
}
這裏是我期待的腳本sshcopy.exp:
set host [lrange $argv 0 0]
set key_file [lrange $argv 1 1]
set password [lrange $argv 2 2]
spawn ssh-copy-id -i $key_file $host
expect -nocase "*password: $" {send "$password\r"; interact} -nocase "*are you sure you want to continue connecting (yes/no)? $" {send "yes\r"} eof{exit}
expect -nocase "*password: $" {send "$password\r"; interact} eof{exit}
您將看到兩個期望上述聲明。第一個語句處理立即通過交互立即詢問密碼(即主密鑰已知)的情況。它還通過回答「是」來處理識別出未知主機的情況。
當第一個期望回答「是」導致密碼被問到時,第二個expect語句被執行。
在您期望的腳本中,使用具有單個索引的'lindex'而不是'lrange'。否則,如果任何參數包含Tcl列表元字符(例如空格或花括號),則可以獲得「驚喜」;這些東西在文件名和密碼中相對可能... – 2010-12-23 11:58:47
另外,在命令行上傳遞密碼是不安全的。 'ps'命令(帶有正確的參數)可以讀取系統中任何進程的完整參數。與環境變量相同(儘管需要一個不同的選項來獲取它們)。安全的方式是通過stdin管道發送它,或者將它放在帶有嚴格權限的文件*中,並在命令行中傳遞該文件的名稱(因爲知道文件名並不能幫助黑客讀取它) )。但是,如果你在一個可以保證沒有入侵者的系統上(很棘手!),保證安全並不重要。 – 2010-12-23 12:02:08