Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash+;期望,在后台运行_Bash_Ssh_Expect_Background Process - Fatal编程技术网

bash+;期望,在后台运行

bash+;期望,在后台运行,bash,ssh,expect,background-process,Bash,Ssh,Expect,Background Process,我正在使用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

我正在使用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}
}
不幸的是,我无法将此置于背景中,我期待着背景,fork+disconnect,但没有运气。 甚至Trined从另一个脚本运行这个

excpect -f script.ex param1 param2 & 

但是没有运气。有什么帮助吗?

假设您的脚本在“前台”工作


这是我很久以前写的剧本。它做你想要的,但不使用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 "$@"

这是一个你可以用来登录然后进行交互的程序。我还没有尝试过所有的ssh选项,但我不认为有任何理由它不起作用。由于我使用了8.6命令“try”,这仅适用于8.6Tcl,但是您可以非常轻松地修改早期版本的try-to-use-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 

要在后台执行expect脚本,请在expect脚本末尾使用
expect eof
。如果您已经定义了
交互
请将其从脚本中删除

更改了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
另一个例子


不幸的是,这与expect不符。执行后,没有ssh进程运行。有两个问题。。。首先,当你把它放在背景中时,“互动”的意义是什么?第二这能在不触及前景的情况下工作吗?好的一点,我是一个新来的人,我刚刚开始对我复制的脚本进行去交互处理。;-)是的,这在手动运行时效果很好。在删除“interact”后效果很好,不幸的是ssh进程在脚本执行几秒钟后就“失效”。我做了一个肮脏的黑客:在脚本末尾添加
sleep 300
,然后通过
expect-f.运行它&如果有人有更好的解决方案-请让我知道。
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
#!/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