符号链接文件后,如何在Ruby中获取原始文件的路径?

gra*_*tur 14 ruby symlink

我有一个带脚本的Ruby脚本/foo/bar/gazook/script.rb.我还在其中创建了一个符号链接$HOME/bin.

现在,我希望我的Ruby脚本访问目录中的其他文件/foo,并保持路径相对,FOO_DIRECTORY = File.expand_path(File.dirname(__FILE__) + "/../../")我的脚本中有一个变量.

问题是如果我从它的符号链接运行我的脚本,这个相对目录是错误的(因为我猜它从不同的位置扩展).

我该如何解决?除了使用绝对路径之外还有其他方法吗?

mu *_*ort 12

您可以使用File.readlink解析符号链接,但您需要先检查File.symlink?.

path = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
Run Code Online (Sandbox Code Playgroud)

然后你可以用path而不是__FILE__.你可能想使用$0的,而不是__FILE__为好,__FILE__是当前文件名,而$0在当前脚本的名称.

  • 对于更通用的解决方案,您需要在循环中解析符号链接,因为一个符号链接可能指向另一个符号链接.另外,你必须检查路径的每个部分:`bin`也可以是符号链接.我推荐`File.realpath`. (6认同)

hag*_*llo 6

要获取相对于脚本位置的任何路径,请始终使用__dir__.

__dir__是一种简洁的说法File.dirname(File.realpath(__FILE__)).它在Ruby> = 2.0中可用.__dir__.

File.realpath(__FILE__)(或Pathname#realpath)与以下相比具有三个优点File.readlink:

  • 它在路径中的任何位置扩展符号链接.readlink仅扩展作为参数最后一部分的路径.
  • 它(递归地)将符号链接解析为符号链接... readlink仅解析第一级.
  • 您根本不必检查是否path是符号链接.因此你可以放弃if File.symlink?.

因此,使用FOO_DIRECTORY = File.join(__dir__, '..', '..')或更好FOO_DIRECTORY = File.dirname(File.dirname(__dir__))