问题
我不是 Tcl 新手,这个问题让我很困惑。我想遍历目录树并处理或忽略那些我无权访问的子目录或文件。这是一个小示例代码:
#!/usr/bin/env tclsh
package require fileutil::traverse
proc errorHandler {absPath errorMessage} {
puts "ERROR: $absPath $errorMessage"
}
# Main
set searchDir /tmp
fileutil::traverse t $searchDir -errorcmd errorHandler
puts "\nFiles in $searchDir:"
t foreach fileName {
puts $fileName
}
输出:
...
couldn't read directory "/tmp/launchd-56801.nzZRsA/": permission denied
while executing
"glob -nocomplain -directory $current -types f -- *"
(procedure "GLOBF" line 2)
invoked from within
"GLOBF $top"
(procedure "::fileutil::traverse::Snit_methodnext" line 44)
invoked from within
"$self next currentfile"
(procedure "::fileutil::traverse::Snit_methodforeach" line 11)
invoked from within
"t foreach fileName {
puts $fileName
}"
(file "./traverser1.tcl" line 17)
我知道问题所在:我无权阅读某些子目录。这就是我在每个文档中放入错误处理程序的原因。但是,从未调用过该错误处理程序。我怀疑这是 Tcl 中的一个错误,但这可能意味着我误解了文档并且没有正确使用包。我感谢任何帮助或建议来解决这个问题。
我的环境
- Mac OS X 山狮
- Tcl 8.5.9
更新
我查看了fileutil::traverse
Mac OS X 10.8.4 Moutain Lion 和 1.15 版(最新版本)附带的 1.12 版的源代码。我发现的是:
method next {fvar} {
# code ...
if {![ACCESS $top]} {
Error ...
...
但是对于 Tcl 8.4 或更高版本,ACCESS 的实现是:
proc ::fileutil::traverse::ACCESS {args} {return 1}
而 Tcl 8.3 的实现是:
proc ::fileutil::traverse::ACCESS {current} {
if {[catch {
set h [pwd] ; cd $current ; cd $h
}]} {return 0}
return 1
}
当我用 8.3 版本替换 8.4 版本时,一切正常。这告诉我这是代码中的错误。我不知道为什么会这样。