TCL / Expect - 交互后,expect_user 不回显

TCL / Expect - After Interact, expect_user doesn't echo

所以我有一个简单的脚本,可以登录网络设备,然后进行交互,让用户调用各种宏。我在下面有一个例子——用户在设备中,点击“!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)"
                }
        }
}

在最简单的形式中,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 带有 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.
          }
}