查找 Ruby 在运行程序时打开的所有当前文件

问题描述 投票:0回答:4

这是一个深奥的请求,对我来说只是理论上的兴趣(换句话说,我没有在生产代码中使用它)。我想知道是否可以找出运行 ruby 程序时涉及的所有文件。也就是说,文件在执行过程中被所述程序编辑(或涉及其他方式,例如在程序中途由 Rails 编辑)。


我知道可以使用
require
并循环遍历对象,排除除

autoload

及其后代之外的所有对象,并且当我禁用垃圾收集时,我使用此方法取得了部分成功(否则列表会随机收缩,这是可以理解的) 。但是,在程序开始时执行此操作会忽略中间所需的那些文件,因此我可以在最后运行相同的代码,并获取所述文件的并集?

    
几个月前我也做了同样的事情。这是我的肮脏的小程序:

ruby metaprogramming
4个回答
3
投票

然后运行你的程序:

File

lsof

3
投票

REQUIRE_FILE = ENV.fetch('REQUIRE_FILE', '/tmp/requires.txt') File.open(REQUIRE_FILE, 'w') Kernel.module_eval do alias_method :require_without_benchmark, :require def require(name) start = Time.now begin require_without_benchmark(name) ensure time = Time.now - start File.write(REQUIRE_FILE, [name, time.to_f].join(',').concat("\n"), mode: 'a') end end end

:

ruby -r ./require-benchmark.rb program.rb
它为您提供当前进程打开的文件

held

但是,该列表还远未完成:一旦执行此行,许多文件已被读取、解析、执行和关闭。

lsof

扫描打开的文件时,它们不再出现在列表中。

追踪


puts `lsof -a -p #{Process.pid}`

(也在 Linux 上)是一个很好的工具,可以实现您想要实现的目标(请参阅此 thread

)。它会提供很多(可能太多)信息:
lsof

strace
现在开始于:

strace -e trace=open -o opened_files.txt ruby hello_world.rb #=> Hello world


“Hello World”脚本有 571 行,“rails runner hello_world.rb”脚本有 112302 (!) 行。

输出文件有许多“ENOENT(没有这样的文件或目录)”行,因此您可能需要解析和过滤它。

对于 macOS 和其他 *nix,应该有

opened_files.txt


请参阅

如何获取 Ruby 中“必需”的文件列表?


0
投票

然后运行你的程序:

File.open

© www.soinside.com 2019 - 2024. All rights reserved.