期望使用套接字将密码发送到后台作业

问题描述

一个小小的 Expect 应用程序中,我想并行启动 ssh-copy-id 以减少整体运行时间。该应用程序运行良好。 Expect 主脚本为每个 ssh-copy-id 启动第二个 Expect 脚本,该脚本生成并处理 ssh-copy-id 输入/输出作为后台作业。这工作正常。 出于测试目的,我通过命令行传递了密码。这在生产中是不可接受的。所以我想让 ssh-copy-id.exp 使用 Tcl 套接字从 main.exp 获取密码。我在 Welch、Jones 和 Hobbs 撰写的“Tcl 和 Tk 中的实用编程”中改编了 Echo 应用程序中的示例。

首先,我只测试了它在两个独立的 Expect REPL 中工作的套接字。在这两个 REPL 中,我都使用了以下代码

proc eserver {} {
    set sock [socket -server accept -myaddr localhost 0]
    # return port
    return [lindex [fconfigure $sock -sockname] 2]
}

set pw spasswort
proc accept {sock addr port} {
    global pw
    fconfigure $sock -buffering line
    fileevent $sock r [list sendpassword $sock $pw]
}

proc sendpassword {sock pw} {
    if {[eof $sock] || [catch {gets $sock line}]} {
        close $sock
        puts "Socket closed by eof or error"
        exit 1
    }
    switch $line {
        quit {
            puts $sock "Quitting connection"
            flush $sock
            close $sock
        }
        sendpw {
            puts $sock $pw
            flush $sock
        }
        # sende Antwort auf client request
        default { puts $sock $line }
    }
}

proc client {port} {
    set sock [socket -async localhost $port]
    fconfigure $sock -buffering line
    return $sock
}

proc req {port str} {
    puts $port $str
    flush $port
}

proc answer {port} {
    gets $port line
    flush $port
    puts stdout $line
    flush stdout
}

在 REPL 1 中,我调用了:

eserver

在 REPL2 中,我调用了:

set c [client $s]
req $c Test
answer $c

req $c TEST
answer $c # returns TEST -> ok

req $c sendpw
answer $c # returns password -> ok

req $c quit # disconnects -> ok

“netstat -anp|grep expect 使用 REPL 1 和 REPL 2 时的输出

tcp        0      0 127.0.0.1:36697         0.0.0.0:*               LISTEN      3209/expect
tcp        0      0 127.0.0.1:36697         127.0.0.1:42873         ESTABLISHED 3209/expect
tcp        0      0 127.0.0.1:42873         127.0.0.1:36697         ESTABLISHED 5163/expect

然后我在 main.exp 中添加了以下代码

proc eserver {} {
    set sock [socket -server accept -myaddr localhost 0]
    return [lindex [fconfigure $sock -sockname] 2]
}

proc accept {sock addr port} {
    global pw
    fconfigure $sock -buffering line
    fileevent $sock r [list sendpassword $sock $pw]
}

proc sendpassword {sock pw} {
    puts SENDPWD
    if {[eof $sock] || [catch {gets $sock line}]} {
        close $sock
        puts "Socket closed by eof or error"
        exit 1
    }
    switch $line {
        quit {
            puts $sock "Quitting connection"
            flush $sock
            close $sock
        }
        sendpw {
            puts $sock $pw
            flush $sock
        }
    }
}

# other deFinitions of procs
# some processing

set pw [passwd]
set serverport [eserver]

更多处理

exec ssh-copy-id.exp $host $user $serverport ...

$serverport 作为参数传递给 ssh-copy-id.exp。在那里可以看到 puts $serverport。

以下代码我已添加到 ssh-copy-id.exp。

proc client {port} {
    puts $port
    puts CLIENT
    set sock [socket -async localhost $port]
    fconfigure $sock -buffering line
    return $sock
}

proc pw-read {sock} {
    puts $sock sendpw
    flush $sock
    gets $sock pw # This command hangs
    puts $pw
    write-file $statuslog [list "$host password received $pw"]
    puts $sock quit
    flush $sock
    return $pw
}

set clientsocket [client $serverport]
set pw [pw-read $clientsocket]

在 proc pw-read 中,连接挂起。我发现了“netstat -anp|grep expect”的不同输出

tcp        0      0 127.0.0.1:41186         0.0.0.0:*               LISTEN      7378/expect

在我看来,ssh-copy-id.exp 似乎没有建立到服务器的连接,尽管服务器已经启动并且似乎在监听。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)