/bin/expect $expect_out 多个正则表达式匹配
/bin/expect $expect_out multiple regex matches
我正在使用以下 expect(1) script to receive a list of users on a Teamspeak server using the Telnet Server Query。
#!/usr/bin/expect
# Spawn TELNET
spawn telnet example.com 10000
expect "TS3"
# Login
send "login $USER $PASS\r"
# Set serverID
send "use sid=$SSID\r"
expect "error id=0 msg=ok"
# Get clients
send "clientlist\r"
这会产生如下输出:
clid=512 cid=3 client_database_id=4 client_nickname=User1 client_type=1|clid=486 cid=3 client_database_id=26 client_nickname=User2 client_type=0
然后,我可以使用下面的代码获取first用户的客户端id(clid=*);
# Get clients
send "clientlist\r"
expect -re "clid=(\d+) "
set clid $expect_out(1,string)
puts "$clid"
# Output: 512
问题:
- 如何获取所有客户端 ID 的列表 (clid=*)
- 我可以使用
for
/foreach
遍历它们吗?
我尝试在这个问题中使用已接受的答案:How do I extract all matches with a Tcl regex?,但是到目前为止我无法将其应用于 send
的输出,而不是变量
有很多方法可以解决这个问题,但最自然的方法可能是执行以下步骤:首先,不要单独使用 expect
和 set
行,而是使用执行 set
作为比赛的结果:
expect -re "clid=(\d+) " { set clid $expect_out(1,string) }
puts "$clid"
这稍微好一点,因为 clid
只有在模式匹配时才会设置。
下一步是使用命令 exp_continue
重新启动匹配过程。它就像一个 for
循环。参见 man expect
。
expect -re "clid=(\d+) " {
set clid $expect_out(1,string)
puts "$clid"
exp_continue
}
要将 clid
变成列表(在 tcl 中实际上只是一个字符串),请使用列表命令:
expect -re "clid=(\d+) " {
lappend clid $expect_out(1,string)
exp_continue
}
puts "$clid"
现在您可以使用
遍历列表
foreach id $clid { puts $id }
你现在应该考虑如何检测clientlist
命令输出的结束,这样你就可以匹配它而不是因为超时而停止。
(Post 如果你的进度受阻,一个新问题)。
expect 使用 \r\n
作为行尾。试试这个:
send "clientlist\r"
expect -re {clientlist\r\n(.+)\r\n}
set ids {}
foreach {_ id} [regexp -all -inline {clid=(\d+)} $expect_out(1,string)] {
lappend ids $id
}
我正在使用以下 expect(1) script to receive a list of users on a Teamspeak server using the Telnet Server Query。
#!/usr/bin/expect
# Spawn TELNET
spawn telnet example.com 10000
expect "TS3"
# Login
send "login $USER $PASS\r"
# Set serverID
send "use sid=$SSID\r"
expect "error id=0 msg=ok"
# Get clients
send "clientlist\r"
这会产生如下输出:
clid=512 cid=3 client_database_id=4 client_nickname=User1 client_type=1|clid=486 cid=3 client_database_id=26 client_nickname=User2 client_type=0
然后,我可以使用下面的代码获取first用户的客户端id(clid=*);
# Get clients
send "clientlist\r"
expect -re "clid=(\d+) "
set clid $expect_out(1,string)
puts "$clid"
# Output: 512
问题:
- 如何获取所有客户端 ID 的列表 (clid=*)
- 我可以使用
for
/foreach
遍历它们吗?
我尝试在这个问题中使用已接受的答案:How do I extract all matches with a Tcl regex?,但是到目前为止我无法将其应用于 send
的输出,而不是变量
有很多方法可以解决这个问题,但最自然的方法可能是执行以下步骤:首先,不要单独使用 expect
和 set
行,而是使用执行 set
作为比赛的结果:
expect -re "clid=(\d+) " { set clid $expect_out(1,string) }
puts "$clid"
这稍微好一点,因为 clid
只有在模式匹配时才会设置。
下一步是使用命令 exp_continue
重新启动匹配过程。它就像一个 for
循环。参见 man expect
。
expect -re "clid=(\d+) " {
set clid $expect_out(1,string)
puts "$clid"
exp_continue
}
要将 clid
变成列表(在 tcl 中实际上只是一个字符串),请使用列表命令:
expect -re "clid=(\d+) " {
lappend clid $expect_out(1,string)
exp_continue
}
puts "$clid"
现在您可以使用
遍历列表foreach id $clid { puts $id }
你现在应该考虑如何检测clientlist
命令输出的结束,这样你就可以匹配它而不是因为超时而停止。
(Post 如果你的进度受阻,一个新问题)。
expect 使用 \r\n
作为行尾。试试这个:
send "clientlist\r"
expect -re {clientlist\r\n(.+)\r\n}
set ids {}
foreach {_ id} [regexp -all -inline {clid=(\d+)} $expect_out(1,string)] {
lappend ids $id
}