在使用符号链接来擦除可执行文件时查找相关库

时间:2008-11-27 02:07:00

标签: ruby symlink

想象一下,你有一个可执行文件foo.rb,库bar.rb按以下方式排列:

<root>/bin/foo.rb
<root>/lib/bar.rb

在foo.rb的标题中,您可以添加以下要求以在bar.rb中引入功能:

require File.dirname(__FILE__)+"../lib/bar.rb"

只要对foo.rb的所有调用都是直接的,这都可以正常工作。如果您将$ HOME / project和symlink foo.rb放入$HOME/usr/bin,那么__FILE__会解析为__FILE__,因此无法找到与$HOME/usr/bin/foo.rb相关的bar.rb foo.rb的目录。

我意识到像rubygems这样的打包系统通过创建一个名称空间来搜索库来解决这个问题,并且还可以使用$:来调整load_path以包含$HOME/project/lib,但似乎好像应该有一个更简单的解决方案。有没有人有过这个问题的经验,并找到了有用的解决方案或配方?

3 个答案:

答案 0 :(得分:12)

我知道这已经很久了,但我发现了这个:

require 'pathname'
APP_ROOT = File.join(File.dirname(Pathname.new(__FILE__).realpath),'..')

答案 1 :(得分:2)

您可以使用此函数来关注任何符号链接并返回真实文件的完整路径:

def follow_link(file)
  file = File.expand_path(file)

  while File.symlink?(file)
    file = File.expand_path(File.readlink(file), File.dirname(file))
  end

  file
end

puts follow_link(__FILE__)

答案 2 :(得分:1)

可能值得一提的是+Pathname对象很好地配合,并且还有Kernel.Pathname方法,因此@ Burke的原始代码可以更短:

require 'pathname'
APP_ROOT = Pathname.new(__FILE__).realpath + "../../lib"