从 stdin 读取程序输出而不是使用 spawn

聚乙烯醇

我正在尝试编写一个 shell 函数,该函数生成一个 ssh 进程并使用密码进行身份验证。然后,我想使用产生的过程来做更多的事情。

这是我到目前为止的功能:

ssh_cmd() {
    ssh $USER@$HOST 2>&1 | expect -c "
        log_user 0
        set timeout 5
        expect password: {
            send \"$PASS\n\"
            sleep 2
            log_user 1
        }
    "
}

然后我想在其他地方使用给定的函数来与 ssh 进程交互,如下所示:

ssh_cmd | expect -c "
    expect '#' {
        send pwd\n
        send exit\n
    }
    expect eof
"

但是,运行ssh_cmd带有-dexpect 选项函数会得到以下结果:

expect version 5.45.4

expect: does "" (spawn_id exp0) match glob pattern "password:"? no
ubnt@ui1's password: expect: timed out

据我了解, 的输出ssh没有正确传输。我知道执行此操作的常用方法是使用spawn,但这意味着进程将在预期退出后被终止,并且我无法使用通用函数来验证 ssh 会话并保持进程处于活动状态以供进一步使用。

格伦杰克曼

你设计的东西是行不通的。Expect 需要expect使用spawn命令解释器内部生成进程将命令的标准输出传递给期望是不够的。

你可以试试这个:

ssh_cmd() {
    # a default bit of code if user does not provide one.
    # you probably want some checking and emit an error message.
    local user_code=${1:-set timeout 1; send "exit\r"; expect eof}
    expect -c "
        log_user 0
        set timeout 5
        spawn ssh -l $USER $HOST
        expect password: {
            send \"$PASS\n\"
            sleep 2
            log_user 1
        }
        $user_code
    "
}

然后像这样调用它:

ssh_cmd '
    expect "#" {
        send pwd\r
        send exit\r
    }
    expect eof
'

请注意,单引号在expect中没有特殊含义,它们只是普通字符:您可能不希望提示是3个字符的模式 '#'

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章