我正在使用expect建立持久的ssh连接
set stb_ip [lindex $argv 0]
spawn -noecho ssh -o ControlMaster=auto -o ControlPath=/tmp/ssh-master-%r@%h:%p -o ConnectTimeout=1 -O exit root@$stb_ip
spawn -noecho ssh -fN -o ControlMaster=yes -o ControlPath=/tmp/ssh-master-%r@%h:%p -o ControlPersist=360 -o ConnectTimeout=1 root@$stb_ip
expect {
-re ".*password:" {send "\r"; interact}
}
不幸的是我无法将其置于背景中,我转向expect_background,fork + disconect但没有运气。 甚至用另一个脚本用
运行它excpect -f script.ex param1 param2 &
但没有运气。有什么帮助吗?
答案 0 :(得分:1)
这是一个可以用来登录然后进行交互的过程。我没有尝试过所有的ssh选项,但我认为没有任何理由不起作用。由于我使用8.6命令“try”,这仅适用于8.6 tcl,但您可以很容易地修改try以使用catch来获取早期版本。
#!/bin/sh
# the next line restarts using wish \
exec /opt/usr8.6b.5/bin/tclsh8.6 "$0" ${1+"$@"}
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 $user@$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
答案 1 :(得分:0)
假设您的脚本在“前景”...
中工作nohup expect -f script.ex param1 param2 &
答案 2 :(得分:0)
这是我很久以前制作的剧本。它做你想要的但不使用Expect(我厌恶)。我不再使用它,我不能保证它仍然可以工作,但它应该让你去。
#!/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 "$@" 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 "$@"
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 "$@"
答案 3 :(得分:0)
要在后台执行expect脚本,请在期望脚本的末尾使用expect eof
。如果您已定义interact
,请将其从脚本中删除。
更改了OP的脚本
set stb_ip [lindex $argv 0]
spawn -noecho ssh -o ControlMaster=auto -o ControlPath=/tmp/ssh-master-%r@%h:%p -o ConnectTimeout=1 -O exit root@$stb_ip
spawn -noecho ssh -fN -o ControlMaster=yes -o ControlPath=/tmp/ssh-master-%r@%h:%p -o ControlPersist=360 -o ConnectTimeout=1 root@$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