Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tcl 如何处理使用fileutil::traverse时被拒绝的权限 问题_Tcl - Fatal编程技术网

Tcl 如何处理使用fileutil::traverse时被拒绝的权限 问题

Tcl 如何处理使用fileutil::traverse时被拒绝的权限 问题,tcl,Tcl,我不是Tcl新手,这个问题困扰着我。我想遍历目录树,处理或忽略那些我没有权限访问的子目录或文件。下面是一个小示例代码: #!/usr/bin/env tclsh package require fileutil::traverse proc errorHandler {absPath errorMessage} { puts "ERROR: $absPath $errorMessage" } # Main set searchDir /tmp fileutil::traverse

我不是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中的一个bug,但这可能意味着我误解了文档,没有正确使用包。我感谢任何帮助或建议来解决这个问题

我的环境
  • Mac OS X Mountain Lion
  • Tcl 8.5.9
更新 我查看了Mac OS X 10.8.4 Mountain Lion和最新版本1.15附带的版本1.12的
fileutil::traverse
的源代码。我发现的是:

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版本时,一切正常。这告诉我这是代码中的一个bug。我不知道为什么会这样。

我找到了一个解决办法,添加了一个预过滤器,它尝试将cd放入目录中,如果目录可以访问,则返回True:

#!/usr/bin/env tclsh

package require fileutil::traverse

# isAccessible: determines if the directory is accessible by attempting to cd into it
proc isAccessible {absPath} {
    set currentDir [pwd]
    if {[catch {cd $absPath}]} {
        set chdirOK False
    } else {
        set chdirOK True
    }
    cd $currentDir
    return $chdirOK
}

# Main
set searchDir /tmp
fileutil::traverse t $searchDir -prefilter isAccessible

puts "\nFiles in $searchDir:"
t foreach fileName {
    puts $fileName
}
更新 多纳尔的建议很好:很有效,很简短,很甜蜜:

proc isAccessible {absPath} {
    return [file readable $absPath]
}
我们甚至可以完全取消编写
isAccessible

fileutil::traverse t $searchDir -prefilter "file readable"

阅读文档时,errorHandler进程是否应该返回false?我已经尝试了两种方法:返回false,然后返回True。这没什么区别。