如何使Ruby的Find.find遵循符号链接?

时间:2010-10-20 01:20:44

标签: ruby find symlink

我有一个文件层次结构,一些子目录是相对的符号链接。我正在使用Ruby's Find.find抓取这些目录并找到一些特定文件。然而,它没有查看任何符号链接的目录(它遵循符号链接的文件)。

查看source code似乎问题是因为它正在使用File.lstat(file).directory?来测试某些内容是否是某个目录。这会为符号链接返回false,但File.stat.directory?会返回true

如何Find.find关注符号链接,缺少猴子修补它以使用File.stat代替File.lstat

6 个答案:

答案 0 :(得分:5)

我遇到了类似的情况,并决定在没有额外宝石的情况下遵循真正的道路。

require 'find'

paths = ARGV

search_dirs = paths.dup
found_files = Array.new

until search_dirs.size == 0
  Find.find( search_dirs.shift ) do |path|
    if File.directory?( path ) && File.symlink?( path )
      search_dirs << File.realdirpath( path )
    else
      found_files << path
    end
  end
end

puts found_files.join("\n")

这种方式不能保留带有符号链接的原始路径,但此刻对我来说还不错。

答案 1 :(得分:3)

使用Daniel J. Berger的文件查找库。它可以作为Ruby宝石使用。然后你可以递归地找到:

require 'rubygems'
require 'file/find'
File::Find.new(:follow => false).find { |p| puts p }

注意:与文档和直觉相反,设置:follow =&gt; false实际上会使File :: Find跟随所有符号链接,至少在我的机器上(Ubuntu 10.04,Ruby 1.8.7,file-find 0.3.4)。

File :: Find还有很多其他选项,比如名称模式,文件类型,atime,ctime,mtime等。看看RDoc。

答案 2 :(得分:1)

为什么不使用Dir呢?它遵循符号链接 或者您可以尝试alib

要让Dir递归查找文件,请尝试使用double asterix Dir["**/*"]

答案 3 :(得分:1)

用循环检查写了另一个选项,只有有限的递归。也适用于jruby。

这是一个要点:https://gist.github.com/akostadinov/05c2a976dc16ffee9cac

答案 4 :(得分:0)

对于其他观看的人,我最终使用Pathname和以下递归代码:

def all_files_under(*paths)
  paths.flatten!
  paths.map! { |p| Pathname.new(p) }
  files = paths.select { |p| p.file? }
  (paths - files).each do |dir|
    files << all_files_under(dir.children)
  end
  files.flatten
end

答案 5 :(得分:0)

这是一个更简单,更有效的递归路径名方法版本:

def find_files(*paths)
  paths.flatten.map do |path|
    path = Pathname.new(path)
    path.file? ? [path.to_s] : find_files(path.children)
  end.flatten
end