Perl Expect/Tcl脚本:如何在不写入标准输出的情况下提示用户?

Perl Expect/Tcl脚本:如何在不写入标准输出的情况下提示用户?,perl,ssh,tcl,expect,Perl,Ssh,Tcl,Expect,在Expect脚本中,如何在不写入标准输出的情况下提示用户?是否可以通过stderr提示用户 我有一个用Perl编写的脚本,可以使用ssh自动化一些测试。为了自动登录ssh,我使用Expect包装了ssh命令,但有时ssh的密码在执行代码的中途过期(例如rsa令牌每30秒刷新一次) 我发现: 除了通过stdout提示用户之外,它工作得很好。我的Perl脚本读取并解析标准输出 我想在不修改Perl代码的情况下将其抽象为我的Expect脚本,可以吗 编辑:我刚刚意识到我的用例很愚蠢,因为我不确定Pe

在Expect脚本中,如何在不写入标准输出的情况下提示用户?是否可以通过stderr提示用户

我有一个用Perl编写的脚本,可以使用ssh自动化一些测试。为了自动登录ssh,我使用Expect包装了ssh命令,但有时ssh的密码在执行代码的中途过期(例如rsa令牌每30秒刷新一次)

我发现:

除了通过stdout提示用户之外,它工作得很好。我的Perl脚本读取并解析标准输出

我想在不修改Perl代码的情况下将其抽象为我的Expect脚本,可以吗

编辑:我刚刚意识到我的用例很愚蠢,因为我不确定Perl将如何与Expect脚本提示符交互,因为我正在从Perl调用Expect脚本。:/但知道是否可以期望写入stderr仍然是件好事。:D


谢谢

您可以尝试访问“文件”
/dev/tty
(它实际上是一个虚拟设备)。这将绕过Perl脚本,直接联系用户终端。一旦打开了密码,就可以使用普通的Expect命令要求用户给出密码(记住在正确的时间用
stty
关闭echo)

否则,最好的选择可能是弹出一个GUI;使用一个小小的Tcl/Tk脚本来实现这一点非常简单:

# This goes in its own script:
pack [label .l -text "Password for [lindex $argv 0]"]
pack [entry .e -textvariable pass -show "*"]
bind .e <Enter> {
    puts $pass
    exit
}
focus .e
就这些。这也是获取密码的一种相当安全的方式,因为密码总是通过(不可拦截的)管道进行通信。唯一的缺点是它需要一个GUI


GUI可能需要变得更漂亮。这只是您需要的基本内容。

一旦进入,密码是否过期无关紧要,除非您有一个非常不寻常的SSH/shell配置。不知道细节,很难给你任何有用的建议。还有,给我们看看你的代码!问题是我需要运行一系列不同的命令。理想情况下,最好生成一个持久ssh会话并通过该会话传递命令,但每次生成一个新会话更容易。我对Perl不太熟悉,无法实现前一种方法。然后,尝试Net::OpenSSH。我没有直接研究Net::OpenSSH模块,但我尝试了Net::SSH:Perl,它具有特定于平台的二进制依赖关系。成功编译该模块有些困难。我假设Net::OpenSSH的情况与此类似,它似乎依赖于二进制ssh客户端。Net::OpenSSH需要OpenSSH客户端,但这适用于大多数Unix/Linux。而且它在Windows上不起作用,但Expect也不起作用。另一个选项是Net::SSH::Any。子流程GUI脚本也可以使用任何其他语言,但我最了解的是Tcl/Tk。谢谢您的回复。我决定修改我的Perl脚本,因为Perl脚本应该知道新密码,这样它就可以在不同的调用中重用它,而无需每次重新验证+1用于显示如何绕过Perl脚本并直接访问用户终端/:)。谢谢
# In your expect script:
set password [exec wish getPass.tcl "foo@bar.example.com"]