【问题标题】:How do I pass a Tcl data structure to Perl with Telnet in between?如何通过 Telnet 将 Tcl 数据结构传递给 Perl?
【发布时间】:2011-08-06 22:34:42
【问题描述】:

我想远程登录到 Cisco 路由器,登录并执行本地存储在路由器闪存中的 Tcl 脚本。这个 Tcl 脚本做了一些处理并且应该返回一个嵌套的散列(首选)或一个代表 XML 文档的字符串。

有没有办法将 Tcl 嵌套散列映射到 Perl 嵌套散列,或返回表示 XML 文档的字符串? Expect 是否允许我执行上述任何操作,以及如何操作?

【问题讨论】:

  • Expect 是一个命令行工具自动化的工具;如果您已经在 Cisco 上编写了脚本,您可以使用 expect 登录并执行它。但是您必须自己编写 TCL 脚本。
  • 我担心的是我是否可以将 Tcl 脚本执行的结果(嵌套散列或字符串)传递给 Perl 嵌套散列或保存字符串的变量。当然,还有后者的做法。
  • “Tcl 嵌套哈希”?那个 Cisco 盒子里有什么版本的 Tcl?
  • 明确地说,Tcl 代码和 Perl 代码之间唯一可以通信的是字符串,但该字符串可以是某种有用格式的文档。

标签: perl serialization tcl telnet expect


【解决方案1】:

将数据序列化为通用交换格式,例如JSON 字符串。

拥有 Tcl 程序emit JSONLoad the JSON 从 Perl 转换成散列。

【讨论】:

  • thanx daxim,有两个问题:我认为 cisco 设备中可用的 tcl shell 没有安装 Yeti,但我会寻找它。其次,假设我们同意 JSON 格式,它看起来是一个很好的方法,我正在寻找的是如何通过 telnet 连接或使用期望传递 tcl 变量(以 json 格式),换句话说,使用上述两个模块的API。
  • 看来 Albert Perrien 你比我更了解,所以你能告诉我如何将 tcl 嵌套哈希(而不是使用 log_user 的字符串)详细返回到 perl 嵌套哈希(命令,等)?
  • rosettacode.org/wiki/JSON#Tcl 上有一个 JSON 生成器,它是纯 Tcl 代码,但它需要 8.6,我打赌不会在那个 Cisco 路由器上。可以通过在那里组装位来构建更受限制的版本(没有类型自动检测)。
  • 我很抱歉,我不是故意要在那儿发脾气的。你在路由器上有什么版本的 Tcl,你能发布一个你试图通过的示例数据结构吗?
【解决方案2】:

Cisco 路由器倾向于运行旧版本的 Tcl,并且没有大量可用的扩展包。这意味着你能做的事情非常有限。幸运的是,对于生成可由 Perl 收集和解析的数据的工作,它实际上相当简单。

让我们使用 JSON 作为交换格式。 (其他也可以。) Daxim 的回答告诉您如何解析 JSON,但这很容易,因为您在可以控制的上下文中运行。如何在那个笨拙的旧 Tcl 中生成 JSON 数据?最简单的方法是使用subst 命令——它在Tcl 中的功能已经很久没有改变了,所以你肯定已经掌握了它——以及一些辅助命令。这是大纲:

proc getFoo {} {
    # Some regular Tcl code to get the value
}
proc getFruit {variety} {
    # Some regular Tcl code to get the value
}
set someIntValue [expr { 1 + 2 * 3 }]    ;#  Or whatever...
set jsonTemplate {
    {
        "foo": [getFoo],
        "bar": {
            "pears":  "[getFruit pears]",
            "apples": "[getFruit apples]"
        },
        "grill": $someIntValue
    }
}
puts [subst $jsonTemplate]

好的,警告时间:我不知道您想要接收什么数据(“嵌套散列”并不多)。您必须在需要时添加引号/反斜杠。将程序放在之前调用subst(在Tcl 中事情的顺序很重要)。

【讨论】:

    【解决方案3】:

    这个expect脚本应该把文件从路由器上取下来,放在/tmp/xferfile.txt中。它需要使用实际生成文件的命令进行修改,因为我没有这些命令,所以我在脚本中为它们留下了占位符。你应该可以使用 Donal 的代码。

    我已经有一段时间没有玩过expect和cisco IOS了,如果这需要你进行一些调试,请多多包涵。

    #!/usr/bin/expect
    set timeout 20
    set ip [lindex $argv 0]
    set user [lindex $argv 1]
    set password [lindex $argv 2]
    set prompt1 "Router>"
    set prompt2 "Router#"
    set prompt3 "bash\$"
    set ctrld [expr ("d" & 01xF)]
    
    spawn ssh "$user\@$ip"
    expect "Password:"
    send "$password\r";
    
    # switch to privileged EXEC level 
    expect $prompt1 { send "enable" }
    
    # ==================================================
    # Modify this line for your needs
    # ==================================================
    expect $prompt2 { send "command to print Tcl hash" }
    
    # Capture output to variable
    set results $expect_out(buffer)
    
    # leave EXEC level
    expect $prompt2 { send "exit" }
    # Command to log out of router
    expect $prompt1 { send "exit" }
    
    # Create text file on localhost
    spawn "#!/bin/bash"
    expect prompt3 { 
        send "cat > /tmp/xferfile.txt"
        sleep 5
        send $results
        send $crtld
        }
    
    expect prompt3 { send "exit" }
    

    【讨论】:

      猜你喜欢
      • 2012-07-06
      • 1970-01-01
      • 1970-01-01
      • 2013-11-15
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      • 2011-03-22
      • 1970-01-01
      相关资源
      最近更新 更多