我有一个期望脚本,我希望它能像一个花哨的ssh程序,在运行命令之前跳过几台机器并在目标机器上设置环境。
我可以使用log_user 0/1关闭/打开expect的输出,这有助于提示密码提示和登录横幅,以及设置环境的命令。
但是,就像ssh一样,一旦我的脚本开始发出命令,我就不想看到发出的命令了。那就是我不想看到"命令"发送"命令之后\ n"。我想看到的只是命令的结果。
如何抑制发送输出,但不抑制结果?
这是预期剧本的片段:
log_user 1
foreach daline [lrange \$argv 0 end] {
send "\$daline\r"
set buffer1
}
所以在此循环之前,我发送密码和设置环境。然后在这个循环中,我运行每个bash命令,该命令被作为参数提供给expect。
感谢。
答案 0 :(得分:9)
许多程序回应他们的输入。例如,如果将date
命令发送到shell,您将看到字符串日期后跟日期。更准确地说,您将看到通常在终端上看到的所有内容。这也包括格式化。
send "date\r"
expect -re $prompt
上述命令以expect_out (buffer)
设置为date\r\nFri Nov 7 20:47:32 IST 2014\r\n
结束。更重要的是,字符串日期已得到回应。此外,每行以\r\n
结尾,包括您使用\r
发送的那一行。日期的回显与send
命令无关。
换句话说,没有办法发送字符串并且发送不回应它,因为send首先没有回显它。产生的过程是。
在许多情况下,生成的进程实际上将回显任务委托给终端驱动程序,但结果是相同的 - 您将进程的输入视为进程的输出。
通常,只能使用log_user
(您在不同的地方使用过)来处理回显输入。例如,假设已生成与远程主机的连接,并且您希望获得远程日期,但未看到日期命令本身已回显。常见的错误是写:
log_user 0 ;# WRONG
send "date\r" ;# WRONG
log_user 1 ;# WRONG
expect -re .*\n ;# WRONG
运行时,log_user
命令无效,因为expect
在expect
命令之前未读取回显的“日期”。解决此问题的正确方法如下:
send "date\r"
log_user 0
expect -re "\n(\[^\r]*)\r" ;# match actual date
log_user 1
puts "$expect_out(l,string)" ;# print actual date only
如果要向远程shell发送大量命令,那么首先禁用所有回显可能会更方便。您可以生成一个shell,然后发送命令stty -echo
,之后您的命令将不再被回显。 stty echo
重新启用回显。
spawn ssh <host>
stty -echo; # Disable 'echo' here
expect something
#Your further code here
stty echo # Enable 'echo' here
#Close of connection