2011-10-11 51 views
3

我使用期望建立一個持久的ssh連接的bash +想到,在後臺

set stb_ip [lindex $argv 0] 

spawn -noecho ssh -o ControlMaster=auto -o ControlPath=/tmp/ssh-master-%[email protected]%h:%p -o ConnectTimeout=1 -O exit [email protected]$stb_ip 
spawn -noecho ssh -fN -o ControlMaster=yes -o ControlPath=/tmp/ssh-master-%[email protected]%h:%p -o ControlPersist=360 -o ConnectTimeout=1 [email protected]$stb_ip 
expect { 
-re ".*password:" {send "\r"; interact} 
} 

可惜我不能設法把這個變成後臺運行,我triend expect_background,叉+ disconect但沒有運氣。 即使是從另一個腳本運行此

excpect -f script.ex param1 param2 & 

但沒有運氣。任何幫助?

回答

0

假設你的腳本在「前臺」的作品...

nohup expect -f script.ex param1 param2 & 
+0

不幸的是,這並不能很好的滿足預期。執行後,沒有ssh進程在運行。 –

+1

兩個問題......首先,當你把這個放在背景中時,「互動」的意義是什麼?第二......這個工作沒有在前臺觸摸它嗎? –

+0

好點,我是新的期望,只是交友我去複製一個腳本。 ;-)是的,這在手動運行時工作正常。 –

0

這裏有一個腳本,我很久以前作出。它做你想要的,但不使用期望(我討厭)。我不再使用它,我不能保證它仍然有效,但它應該讓你去。

#!/bin/sh 
# 
# Persistent ssh: Automatically create persistent ssh connections using OpenSSH 4.0 

[ -z "$USER" ] && USER=`whoami` 
MASTERSOCKDIR="/tmp/pssh-$USER" 
MASTERSOCK="$MASTERSOCKDIR/%r-%h-%p" 

# Check if master is running 
output=`ssh -o ControlPath="$MASTERSOCK" -O check "[email protected]" 2>&1` 
if [ $? -ne 0 ]; then 
     case "$output" in 
     Control*) 
       # Master not running, SSH supports master 

       # Figure out socket filename 
       socket=`echo "$output" | sed -n -e 's/[^(]*(\([^)]*\)).*/\1/p' -e '1q'` 

       # Clean old socket if valid filename 
       case "$socket" in 
       "$MASTERSOCKDIR"/*) rm -f "$socket" >/dev/null 2>&1 ;; 
       esac 

       # Start persistent master connection 
       if [ ! -d "$MASTERSOCKDIR" ]; then 
         mkdir "$MASTERSOCKDIR" 
         chmod 700 "$MASTERSOCKDIR" 
       fi 
       ssh -o ControlPath="$MASTERSOCK" -MNf "[email protected]" 
       if [ $? -ne 0 ]; then 
         echo "$0: Can't create master SSH connection, falling back to regular SSH" >&2 
       fi 
       ;; 
     *) 
       # SSH doesn't support master or bad command line parameters 
       ERRCODE=$? 
       echo "$output" >&2 
       echo "$0: SSH doesn't support persistent connections or bad parameters" >&2 
       exit $ERRCODE 
       ;; 
     esac 
fi 
exec ssh -o ControlPath="$MASTERSOCK" -o ControlMaster=no "[email protected]" 
1

繼承人您可以使用登錄,然後進行交互的過程。我沒有嘗試過所有的ssh選項,但我沒有看到任何理由不起作用。由於我使用8.6命令「try」,因此這僅適用於8.6 tcl,但是您可以很容易地修改嘗試在較早版本中使用catch。

#!/bin/sh 
# the next line restarts using wish \ 
exec /opt/usr8.6b.5/bin/tclsh8.6 "$0" ${1+"[email protected]"} 

if { [ catch {package require Expect } err ] != 0 } { 
    puts stderr "Unable to find package Expect ... adjust your auto_path!"; 
} 
proc login { user password cmdline } { 
    set pid [spawn -noecho {*}$cmdline ] 
    set bad 0; 
    set done 0; 
    exp_internal 0; # set to one for extensive debug 
    log_user 0;  # set to one to watch action 
    set timeout 10 
    set passwdcount 0 
    set errMsg {} 
    # regexp to match prompt after successfull login you may need to change 
    set intialpromptregexp {^.*[\$\#>]} 
    expect { 
     -i $spawn_id 
     -re $intialpromptregexp { 
     send_user $expect_out(0,string); 
     set done 1 
     } 
     -re {.*assword:} { 
     if { $passwdcount >= 1 } { 
      lappend errMsg "Invalid username or password for user $user" 
      set bad 1 
     } else { 
      exp_send -i $spawn_id "$password\r" 
      incr passwdcount 
      exp_continue; 
     } 
     } 
     -re {.*Host key verification failed.} { 
     lappend errMsg "Host key verification failed." 
     set bad 1 
     } 
     -re {.*onnection refused} { 
     lappend errMsg "Connection Refused" 
     set bad 1 
     } 
     -re {.*onnection closed by remote host} { 
     lappend errMsg "Connection Refused" 
     set bad 1 
     } 
     -re {.*Could not resolve hostname (.*): Name or service not known} { 
     lappend errMsg "Host invalid: Could not resolve hostname in $cmdline : Name or service not known" 
     set bad 1 
     } 
     -re {\(yes/no\)\?} { 
     exp_send -i $spawn_id "yes\r" 
     exp_continue; 
     } 
     timeout { 
     lappend errMsg "timeout \[[expr { [clock seconds] - $start } ]\]" 
     set bad 1 
     } 
     fullbuffer { 
     lappend errMsg " buffer is full" 
     exp_continue; 
     } 
     eof { 
     puts "Eof detected " 
     set bad 1 
     set done 1 ; 
     } 
    } 
    if { $bad } { 
     throw CONNECTION_ERROR [join $errMsg \n ] 
    } 
    return $spawn_id 
} 
# get login information in somehow in this case from command line 
set user [lindex $argv 0] 
set passwd [lindex $argv 1] 
set host [lindex $argv 2 ] 
try { 
    set spawn_id [login $user $passwd "ssh -X [email protected]$host" ] 
} trap CONNECTION_ERROR a { 
    puts "CONNECTION ERROR: $a" 
    exit 1 
} 
interact 
set exitstatus [ exp_wait -i $spawn_id ]; 
catch { exp_close -i $spawn_id }; 
# more clean up here if you want 
0

要在後臺執行期望腳本,請在期望腳本的末尾使用expect eof。如果你已經定義interact從你的腳本中刪除它。 OP

set stb_ip [lindex $argv 0] 

spawn -noecho ssh -o ControlMaster=auto -o ControlPath=/tmp/ssh-master-%[email protected]%h:%p -o ConnectTimeout=1 -O exit [email protected]$stb_ip 
spawn -noecho ssh -fN -o ControlMaster=yes -o ControlPath=/tmp/ssh-master-%[email protected]%h:%p -o ControlPersist=360 -o ConnectTimeout=1 [email protected]$stb_ip 
expect { 
-re ".*password:" {send "\r"; interact} 
} 
expect eof 

的其他例子的 [1]

變更腳本。

#!/usr/bin/expect -f 

set host "host" 
set password "password" 

spawn ssh $host 

expect { 
"(yes/no)?"  { 
     send -- "yes\r" 
     exp_continue 
     } 
"*password:*" { 
     send -- "$password\r" 
     } 
} 

##Removing this: 
#interact 

##And adding this: 
expect eof 
exit