2015-12-02 134 views
2

我已經寫了一個腳本,它使用kpcli連接到本地keepass數據庫並期望從數據庫中獲取憑證,然後通過ssh連接。該腳本可以正常工作,但是通過SSH成功​​登錄到遠程主機後,會話將在大約5秒鐘後終止。期待,Bash和kpcli

#!/bin/bash 

firewall="$1" 
keepass_password="******" 
keepass_db="/media/sf_VM_shared/kdb.kdb" 
keepass_fw_dir="General/Network/Firewalls/SSH" 
firewall_user="admin" 


echo -e "\n" 
echo "Connecting to keepass Database..." 

function get_creds { 
    expect <<- DONE 
    set timeout 10 
    spawn kpcli 
    match_max 100000000 
    expect "kpcli:/>" 
    send "open $keepass_db\n" 
    expect "password:" 
    send "$keepass_password\n" 
    expect ">" 
    send "cd $keepass_fw_dir\n" 
    expect "SSH>" 
    send "show -f $firewall\n" 
    expect ">" 
DONE 

} 

credentials=$(get_creds) 
ssh_info=$(echo "$credentials" | grep 'Title:\|Pass:\|Notes:' | sed -e 's/^.*:  //') 
ip_address=$(echo "$ssh_info" | awk 'NR==3') 
firewall_name=$(echo "$ssh_info" | awk 'NR==1') 
firewall_pass=$(echo "$ssh_info" | awk 'NR==2') 
echo -e "\n" 
echo "------Firewall Information-------" 
echo -e Firewall IP:'\t \t'   "$ip_address" 
echo -e Firewall Name:'\t \t'   "$firewall_name" 
echo -e Firewall Password:'\t'   "$firewall_pass" 
echo "----------------------------------" 
echo -e "\n" 
echo "Connecting to firewall module with user "admin"..." 

function ssh_connect { 
expect <<- DONE 
spawn ssh -v -oStrictHostKeyChecking=no -oCheckHostIP=no [email protected]$ip_address 
expect "password" 
     sleep 5 
     send "$firewall_pass\n" 
     expect continue 
     expect eof 

DONE 
} 

ssh_connect 
+1

有一堆'回聲 「$ FOO」 的|當bash本身可以通過內置的功能輕鬆地(更高效地)提取這些東西時,awk'行就很愚蠢。考慮:'{讀-r ip_address;讀-r防火牆名稱;讀-r firewall_pass; } <<<「$ ssh_info」' –

+1

此外,'echo -e'不符合POSIX標準(請參閱http://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html)。使用'printf'。另外,避免使用'function'關鍵字 - 它不會超過兼容函數定義語法,但會使您的代碼與其他shell不必要地兼容。 –

+0

@CharlesDuffy同意100%,但認爲我應該指出你的可變訂單是不正確的。 OP代碼中的「NR」值不合適。這些行按順序是'name','pass','ip'。 –

回答

0

我設法得到這個工作有以下幾點:

expect -c ' 
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no [email protected]'$ip_address' 
expect "(password)" 
send '$firewall_pass' 
expect "(*)" 
interact' 
1

我把它你指的是你的ssh_connect功能,我再假設你想一旦你驗證自己,SSH會話是互動的。您需要預期的interact命令將控制權傳遞給用戶。

function ssh_connect { 
    expect <<- DONE 
     spawn ssh -v -oStrictHostKeyChecking=no -oCheckHostIP=no [email protected]$ip_address 
     expect "password" 
     send -- "$firewall_pass\r" 
     interact 
DONE 
} 
  • 在寄期望於「按下回車鍵」回車\r這是習慣。
  • 使用send -- "$variable"中的雙連字符來防止變量的第一個字符爲連字符時的情況。
+0

無論是這個還是「超時」問題。但假設代碼完整,這更有可能。 –

+0

我試過使用'交互',但我甚至沒有登錄到遠程shell,如果我這樣做。如果我刪除'expect eof',那麼我不會登錄到shell。我剛回到本地shell。 – user1776732

+0

使用'expect -d << DONE'來期望告訴你在後臺發生了什麼。 –