这是一段非常简单的代码,通过打开管道在后台执行 ping 操作。为此,将“文件名”的第一个字符设置open
为 a |
,当“文件名”的其余部分被解释为命令行参数的 Tcl 列表时,就像在exec
:
proc doPing {host} {
# These are the right sort of arguments to ping for OSX.
set f [open "|ping -c 1 -t 5 $host"]
fconfigure $f -blocking 0
fileevent $f readable "doRead $host $f"
}
proc doRead {host f} {
global replies
if {[gets $f line] >= 0} {
if {[regexp "Reply from $host" $result]} {
# Switch to drain mode so this pipe will get cleaned up
fileevent $f readable "doDrain $f"
lappend replies($host) 1
incr replies(*)
}
} elseif {[eof $f]} {
# Pipe closed, search term not present
lappend replies($host) 0
incr replies(*)
close $f
}
}
# Just reads and forgets lines until EOF
proc doDrain {f} {
gets $f
if {[eof $f]} {close $f}
}
您还需要运行事件循环;这可能是微不足道的(您正在使用 Tk)或可能需要显式(vwait
)但不能集成到上述内容中。但是您可以使用一个聪明的技巧来运行事件循环足够长的时间来收集所有结果:
set hosts 172.35.122.18
set replies(*)
foreach host $hosts {
for {set i 0} {$i < 20} {incr i} {
doPing $host
incr expectedCount
}
}
while {$replies(*) < $expectedCount} {
vwait replies(*)
}
然后,只需查看replies
数组的内容即可获得所发生情况的摘要。