2016-08-05 64 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進行了字符串分割,它們將會是空格),星號也是如此(不會被替換爲當前工作目錄)。 –