这是一个深奥的请求,对我来说只是理论上的兴趣(换句话说,我没有在生产代码中使用这个)。我想知道是否有可能找出运行ruby程序时涉及的所有文件。也就是说,在执行过程中,该程序涉及的文件require
d(或其他方式,例如在程序中途由Rails执行的autoload
ed)。
我知道可以使用ObjectSpace
并循环遍历对象,排除除File
及其后代之外的所有对象,并且在禁用垃圾收集时,我使用此方法取得了部分成功(否则列表会随机收缩,这是可以理解的)。然而,在程序开始时这样做会忽略中间需要的那些文件,所以我可以在最后运行相同的代码,并获得所述文件的联合?
4条答案
按热度按时间pobjuy321#
几个月前我也做了同样的事情。下面是我的小程序:
字符串
然后运行你的程序:
型
dauxcl2d2#
lsof
在Linux上,你可以使用
lsof
:字符串
它给你当前进程打开的文件。
但是,这个列表还远远没有完成:一旦这一行执行,许多文件已经被读取、解析、执行和关闭。
当
lsof
扫描打开的文件时,它们不再出现在列表中。strace
strace
(也在Linux上)是一个很好的工具,可以实现你想要实现的目标(参见thread)。它将提供给予很多(可能太多了)信息:型
opened_files.txt
现在开始于:型
它有571行用于“Hello World”脚本,112302(!)用于“rails runner hello_world.rb”脚本。
输出文件有许多“ENOENT(No such file or directory)”行,因此您可能需要对其进行解析和过滤。
对于macOS和其他 *nix,应该有
dtrace
。hrysbysz3#
有关所需文件,请参阅How do I get a list of files that have been
required
in Ruby?。有关gem的所有依赖项,请参阅How do I find out all the dependencies of a gem?常量
$LOADED_FEATURES
保存了一个数组,其中包含了所有文件,这些文件的路径都是用require加载的,不仅仅是gem本身,还有所有涉及到的文件。在脚本的末尾尝试使用$LOADED_FEATURES.dup.uniq
。对于File打开的普通文件,你可以覆盖
IO.open
和/或File.open
以及姐妹方法read,binread等,就像Karaszi在他的回答中所展示的那样。8ljdwjyq4#
基于KARAZI的答案,这里有一个显示文件路径的版本:
字符串
然后运行你的程序:
型