【问题标题】:parse information from expect command从expect命令解析信息
【发布时间】:2013-11-07 10:30:36
【问题描述】:

我需要解析来自telnet/ssh 命令的结果数据并对数据采取行动。

作为示例,我想与 spawn 会话(此处为ssh)进行交互,列出当前目录中的文件并仅收集某个扩展名的文件,以便稍后对这些文件执行命令仅限。

到目前为止我得到了什么:

#!/usr/bin/expect

set timeout 3
match_max 10000
set prompt {$ }

spawn ssh $user@$host
expect "password: "
send $pw\r
expect $prompt

# here's the command I need to parse resulting data
send "ls -1\r"
expect -re {(.*)\.log} {
    set val $expect_out(1,string)
    puts "LOG file: $val"
    exp_continue
}

该脚本打开一个ssh 会话,发送命令并显示所有当前目录(日志和其他)中的文件,但我需要处理与给定模式匹配的每个文件,我该怎么做这样做?

脚本输出:

$  DATA: 
0_system.log
1_system.log
2_system.log
3_system.log
a.log
a.sh
blah
b.sh
data.csv

【问题讨论】:

  • 不要认为你的正则表达式需要大括号和引号
  • @vogomatix 谢谢!已更新。
  • 这真的解决了问题吗?我上次做 Expect 大约是 8 年前 :-)
  • 我认为您的正则表达式应该放在大括号中 - 请参阅下面的官方回答和讨论。如果您能告诉我们引号或大括号是否有效,我将不胜感激。

标签: linux ssh tcl expect


【解决方案1】:

首先...ls -1 *.log 会不会更容易,并且做到这一点?

也就是说,我发现通常你在使用(.*)时必须非常小心,它有时会产生意想不到的结果。

我会选择“任何字母数字字符加下划线”(如果这适用于您的文件名) - 请参阅下面我建议的期望块。另外,请记住,通过使用$expect_out(1,string),您只保存了文件名,没有扩展名 - 不确定这是否是您想要的。如果你想要整个事情,$expect_out(0,string) 在这种情况下是要走的路。

这样就可以了:

expect -re "(\[a-zA-Z0-9_\]*)\.log" {
    set val $expect_out(1,string)
    puts "LOG file: $val"
    exp_continue
}

希望对您有所帮助! 詹姆斯

【讨论】:

  • ls -1 *.log 在我的情况下不起作用,因为我只是显示我从设备获得的输出类型。它实际上是一个专有命令,而不是真实场景中的ls
  • 在这种情况下,正确使用正则表达式是关键。更新我的脚本现在可以正常工作了,谢谢!
【解决方案2】:

更正后的 Expect 可能应该是:

expect {
    -re {(.*)\.log} {
        set val $expect_out(1,string)
        puts "LOG file: $val"
        exp_continue;
    }
}

【讨论】:

  • 更可能是{(.*)\.log},因为反斜杠是双引号中的 Tcl 引用字符,因此 \. 最终被解释为 .,这不是这里想要的。
  • 你可能是对的,就像我说我上次做 Tcl 和 Expect 大约 8 年前一样,但是我查看了 Don Libes 的书,\n 和 \r 肯定被双引号所接受,所以我' 不完全确定 \ 会发生什么。无论如何,我已经修改了我的示例。
  • 使用{(.*)\.log} 作为正则表达式是正确的。但是我仍然在 $val 中获得了整个文件列表,好像正则表达式不起作用
  • 正则表达式可能是贪婪的。 (.*) 可能正在捕获直到最后一个日志的所有内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 2013-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多