После символической ссылки на файл, как мне получить путь к исходному файлу в Ruby? - PullRequest
14 голосов
/ 16 декабря 2011

У меня есть скрипт Ruby с путем /foo/bar/gazook/script.rb.Я также создал символическую ссылку на него в $HOME/bin.

Теперь я хочу, чтобы мой скрипт на Ruby обращался к другому файлу в каталоге /foo, и чтобы сохранить относительные пути, у меня есть переменная FOO_DIRECTORY = File.expand_path(File.dirname(__FILE__) + "/../../") вмой сценарий.

Проблема в том, что если я запускаю свой сценарий из его символической ссылки, этот относительный каталог неверен (так как я предполагаю, что он расширяется из другого места).

Как это исправить?Есть ли способ, кроме использования абсолютного пути?

Ответы [ 4 ]

12 голосов
/ 17 декабря 2011

Вы можете использовать File.readlink для разрешения символической ссылки, но сначала нужно проверить File.symlink?.

path = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__

Тогда вы можете работать с path вместо __FILE__. Вы также можете использовать $0 вместо __FILE__, __FILE__ - текущее имя файла, тогда как $0 - имя текущего скрипта.

5 голосов
/ 07 апреля 2015

Чтобы получить любой путь относительно местоположения вашего скрипта, всегда используйте __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__))

2 голосов
/ 26 июля 2014

Попробуйте это

require 'pathname'
p File.dirname(Pathname.new(__FILE__).realpath)
0 голосов
/ 17 декабря 2011

Попробуйте:

FOO_DIRECTORY = File.expand_path("../../../", __FILE__)

Я говорю, что проблема в том, что ваш файл символической ссылки интерпретирует File.dirname(__FILE__)

...