TCL / Expect - 在Interact之后,expect_user不回显

时间:2015-05-07 23:12:34

标签: ssh tcl expect

所以我有一个简单的脚本登录到网络设备,然后交互允许用户调用各种宏。我在下面有一个示例 - 用户在设备中,点击“!p”,然后脚本希望用户输入命令。

一切正常,但程序没有回显用户输入的内容,因此他们无法纠正错误类型。

我目前的解决方案是stty echo之前的expect_user和之后的stty -echo。但是在此解决方案中,会捕获退格键和箭头键,因此用户仍然无法纠正错误类型。

我不确定如何解决这个问题,但我认为正在发生的是生成的程序控制了STDOUT,所以当调用expect_user时,它就在后台。

set hostname 10.0.0.1
set password 1234qwer

spawn ssh -o StrictHostKeyChecking=no $hostname
expect {
        "assword:" {
                        send "$password\r"
                        expect "#"
        }
}
interact {
        "!p" {
                send_user "\nInput command: "
                expect_user -re "(.*)\r" {
                        puts "\n$expect_out(1,string)"
                }
        }
}

1 个答案:

答案 0 :(得分:1)

最简单的形式是interact命令在用户和当前生成的进程之间建立连接。 用户的终端进入原始模式,以便连接是透明的。

原始模式是一种特定类型的面向字符的模式,其中没有对输入字符应用特殊解释。例如,Ctrl-C不再用作中断,Ctrl-D不再用作eof原始模式的反面是熟化模式。它代表了面向行的模式的最常见形式。

因此,为了实现您想要的效果,您必须在提示用户输入之前将终端置于熟食模式。

stty -raw echo; # Put the terminal to cooked mode, echo is enabled.
stty raw -echo; # Put the terminal to raw mode, echo is disabled.

由于终端处于原始模式进行交互,因此它根本不会回显字符,您可能已经注意到了这些字符。即,当您输入!p时,您根本看不到它。有一个选项可以让它回应。带-echo的{​​{1}}标志可以完成这项工作。

例如,interact会回显interact -echo "Hello" {puts " World"},而用户则会输入Hello。这也可以添加到您的脚本中。

添加所有这些方面,最终的代码可以写成如下,

interact {
         -echo "!p" {
                send_user "\nInput command: "
                stty -raw echo; # Enabling cooked mode
                expect_user -re "(.*)\n" {
                        set input $expect_out(1,string)
                        puts "You have typed : $input"
                        # Process the user input as per your idea
                }
                stty raw -echo; # Enabling raw mode again.
          }
}