2015-12-02 140 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'来期望告诉你在后台发生了什么。 –