如何在 Tcl 中将 if 语句与 expect 一起用于 telnet?

how to use if statements with expect in Tcl for telnet?

自动 telnet 获取天气的会话:

thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ 
thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ tclsh main.tcl 


connect to wunderground with:
-----------------
1)  noControlFlow
2)  connect


1
spawn telnet rainmaker.wunderground.com
getting weather for nyc
Trying 35.160.169.47...
Connected to rainmaker.wunderground.com.
Escape character is '^]'.
------------------------------------------------------------------------------
*               Welcome to THE WEATHER UNDERGROUND telnet service!            *
------------------------------------------------------------------------------
*                                                                            *
*   National Weather Service information provided by Alden Electronics, Inc. *
*    and updated each minute as reports come in over our data feed.          *
*                                                                            *
*   **Note: If you cannot get past this opening screen, you must use a       *
*   different version of the "telnet" program--some of the ones for IBM      *
*   compatible PC's have a bug that prevents proper connection.              *
*                                                                            *
*           comments: jmasters@wunderground.com                              *
------------------------------------------------------------------------------

Press Return to continue:

Press Return for menu
or enter 3 letter forecast city code-- nyc
Weather Conditions at 03:51 AM EDT on 10 May 2020 for New York JFK, NY.
Temp(F)    Humidity(%)    Wind(mph)    Pressure(in)    Weather
========================================================================
  40          55%         WEST at 20       30.08      Partly Cloudy

Forecast for New York, NY
319 am EDT sun may 10 2020

.Today...Sunny. Highs in the lower 60s. West winds 15 to 20 mph. 
.Tonight...Mostly cloudy. A chance of showers after midnight.
Lows in the upper 40s. Southwest winds 15 to 20 mph, diminishing
to 5 to 10 mph after midnight. Chance of rain 30 percent. 
.Monday...Mostly cloudy with a chance of showers. A slight chance
of thunderstorms in the afternoon. Highs in the lower 60s. West
winds 10 to 15 mph. Chance of rain 50 percent. 
.Monday night...Mostly cloudy with a slight chance of showers in
the evening, then mostly clear after midnight. Lows in the lower
40s. Northwest winds 15 to 20 mph. Chance of rain 20 percent. 
.Tuesday...Sunny. Highs in the upper 50s. Northwest winds 10 to
15 mph. 
.Tuesday night...Partly cloudy. Lows in the lower 40s. 
.Wednesday...Sunny. Highs in the lower 60s. 
.Wednesday night...Mostly clear in the evening, then becoming
   Press Return to continue, M to return to menu, X to exit: thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ 
thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ 

代码:

package provide weather  1.0
package require Expect

namespace eval ::wunderground {
}

#works
proc ::wunderground::noControlFlow {city} {
    variable telnet [spawn telnet rainmaker.wunderground.com]
    puts "getting weather for $city"

    expect "Press Return to continue:"
    send "\r"

    expect "or enter 3 letter forecast city code--"
    send "$city\r"

    expect "X to exit"
    send "x"


}

如何向上述脚本添加一点逻辑或控制流?

例如,要从 proc 本身打印一些硬编码的城市,并以数字形式向 select 显示菜单?

类似于 main 脚本:

lappend auto_path /home/thufir/NetBeansProjects/spawnTelnet/telnet/weather
package require weather 1.0


puts "\n\nconnect to wunderground with:"
puts "-----------------"
puts "1)\tnoControlFlow"
puts "2)\tconnect\n\n"


set a [gets stdin]


if {$a == 1 } {
   wunderground::noControlFlow "nyc"
} else {
   wunderground::connect "nyc"
}

是的,显然 wunderground 提供了 select 的城市菜单。只是想添加一些分支以进行启发。

期待 ,我相信 -i 开关 expect 语句。

我已经将 expect 的 man 页面发送到我的 kindle,正在考虑购买 expect 的书。

您可以将 ifforeach 等普通 Tcl 控制流结构与 Expect 命令一起使用。 (您已经通过使用 proc 完成了其中的一些工作。)唯一真正棘手的一点(尤其是循环和 Expect)是您需要考虑您正在做什么以及您正在做什么正在自动化。

您最终得到的结果可能看起来像这样

proc ::wunderground::multipleCities {args} {
    variable telnet [spawn telnet rainmaker.wunderground.com]
    puts "getting weather for $city"

    expect "Press Return to continue:"
    send "\r"

    foreach city $args {
        expect "or enter 3 letter forecast city code--"
        send "$city\r"
    }

    expect "X to exit"
    send "x"
}

除了我认为您可能应该以某种方式将循环中的 expect 构造为在概念上位于 send 之后,以便您可以处理获取特定城市的值的结果。您可能需要确定获取数据后返回的常见稳定提示。