2010-06-29 110 views
7

我正在努力解決在ssh中自動輸入密碼的經典問題,並像 其他人一樣,我在黑暗中磕磕絆絆地期待着。最後,我拼湊了一個腳本,還挺工作:退出期望{}沒有超時

#!/usr/bin/expect -f 

# command line args 
set user_at_host [lrange $argv 0 0] 
set password [lrange $argv 1 1] 

set timeout 1 

# ssh command 
spawn ssh -S ~/.ssh/tmp.$user_at_host -M -N -f $user_at_host 

# deal with ssh prompts 
expect { 
    "*yes/no*" { send "yes\r" ; exp_continue } 
    "*assword:" { send "$password\r" ; exp_continue } 
} 

此腳本終止只感謝timeout 1線,沒有它,它只是掛起,並且只能通過用戶交互(^C)終止。

spawn行是一個簡單的ssh命令時,腳本立即終止,但是這是not your straight forward ssh。可能不同的是-f選項,它使它在後臺運行(但我嘗試了腳本沒有它無濟於事)。

,我讀了interactexpect eof可能有幫助,但我沒能找到正確的咒語,將真正做到這一點。

我的問題(我認爲)是如何使期望腳本,產生後臺進程,終止沒有超時?


編輯:我應該預期(沒有雙關語意)的「使用密碼的ssh認證」的答案。雖然這是一個很好的建議,但它並不是我的方案中的適當解決方案:在受信任的環境中自動測試安裝了vanilla的系統,其中將可信密鑰添加到映像是不可取/可能的。

回答

1

好了,我發現,似乎工作置換 -

首先我需要一個wrapper劇本完成後,將給出指示:

#!/bin/bash 
"[email protected]" 
echo "done" 

然後期望腳本變爲:

#!/usr/bin/expect -f 
set user_at_host [lrange $argv 0 0] 
set password [lrange $argv 1 1] 

# no need for timeout 1 
set timeout 60 

# use the wrapper 
spawn wrapper ssh -S ~/.ssh/tmp.$user_at_host -M -N -f $user_at_host 

expect { 
    "*yes/no*" { send "yes\r" ; exp_continue } 
    "*assword:" { send "$password\r" ; exp_continue } 
    # use the wrapper 
    "done" { exit } 
} 

感謝道格拉斯Leeder先生(投票決定)和glenn jackman(投票贊成)的有用建議。我會很樂意不接受這個答案,並且接受更優雅的答案,也許是一個取消了包裝腳本的答案。

謝謝大家的關注。

1

這個循環:

expect { 
    "*yes/no*" { send "yes\r" ; exp_continue } 
    "*assword:" { send "${password}\r" ; exp_continue } 
} 

不能終止,除了超時或EOF任何方式;兩條匹配線將會是exp_continue,所以請再次循環。

進入背景意味着基本上分岔;父母死亡,孩子繼續連接。

個人而言,我解決了互動元素不同:

  1. 主機密鑰:要麼一次手動連接,或直接在SSH known_hosts文件插入鑰匙。
  2. 密碼:我會使用私人/公鑰認證。可以使用代理來存儲密鑰,也可以使用無密碼密鑰。
+0

有沒有辦法之後'*密碼才能退出:'?當我試圖用其他任何東西代替'exp_continue'時,它立即退出,但似乎沒有'發送''$ {密碼}'。 – 2010-06-29 14:43:39

+0

也許一個'睡眠1'或'期待eof'或'wait'? – 2010-06-29 16:20:27

+0

對不起,我正在拼命掙扎,也許你可以幫我減少我必須測試的排列次數:應該等待eof /睡眠1在'expect {...}之內還是之外「 '「循環」? – 2010-06-29 16:35:19

7

你可能想:

expect { 
    "*yes/no*" { send "yes\r" ; exp_continue } 
    "*assword:" { send "${password}\r" } 
} 
expect $the_prompt 
send "exit\r" 
expect eof 

UPDATE

我錯過了你是通過SSH發送命令。我認爲,所有你需要的是這樣的:

spawn ssh [email protected] foo bar baz 
expect { 
    "*yes/no*" { send "yes\r" ; exp_continue } 
    "*assword:" { send "${password}\r" } 
    eof 
} 

你會打eoffoo命令完成時。

+0

這並沒有解決我的問題,但給了我一個重要的線索:完成後我需要某種提示。看到我自己的答案。謝謝。 – 2010-06-30 06:22:38

0

的方式,我做到了:

set user "****"  
set host "127.0.0.1"  
spawn shh [email protected]$host  
expect "password: "  
send "**??54"  
expect "$"  
interact 

(即回答您如何使用交互方式)