2011-12-16 7 views
14

Mam skrypt w języku Ruby ze ścieżką /foo/bar/gazook/script.rb. Stworzyłem także dowiązanie symboliczne do niego w $HOME/bin.Po dowiązaniu symbolicznym pliku, jak uzyskać ścieżkę oryginalnego pliku w Ruby?

Teraz chcę, aby mój skrypt Ruby uzyskał dostęp do innego pliku w katalogu /foo, a aby zachować względne ścieżki, w moim skrypcie mam zmienną FOO_DIRECTORY = File.expand_path(File.dirname(__FILE__) + "/../../").

Problemem jest to, że jeśli uruchomię mój skrypt od jego miejsce linku, to względny katalog jest niewłaściwy (ponieważ myślę, że jego rozszerzenie z innej lokalizacji).

Jak to naprawić? Czy istnieje sposób poza użyciem bezwzględnej ścieżki?

Odpowiedz

10

Można użyć File.readlink rozwiązać dowiązania ale będziemy chcieli sprawdzić File.symlink? pierwszy.

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

Następnie można pracować z path zamiast __FILE__. Może chcesz użyć $0 zamiast __FILE__ jak również, __FILE__ jest obecny podczas $0 nazwa_pliku to nazwa bieżącego skryptu.

+3

Aby uzyskać bardziej ogólne rozwiązanie, musisz rozwiązać dowiązania symboliczne w pętli, ponieważ jedno dowiązanie symboliczne może wskazywać na inny, a dodatkowo musisz sprawdzić każdą część ścieżki: 'bin' może być również dowiązanie symboliczne. Polecam 'File.realpath'. – hagello

-1

Spróbuj tego:

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

I powiedzmy, że problem jest, że plik jest dowiązaniem interpretacji File.dirname(__FILE__)

+0

'expand_path' nie rozwiąże dowiązania i określić' dir_string' nie pomoże: [ "Ścieżki względne odniesione są z bieżącego katalogu roboczego proces, chyba że podano dir_string, w którym to przypadku zostanie użyty jako punkt wyjścia. "] (http://ruby-doc.org/core-1.9.3/File.html#method-c-expand_path). Ponadto drugim argumentem 'expand_path' powinien być * katalog *, a nie nazwa pliku. –

+0

OK, utworzyłem plik testowy, dowiązanie symboliczne w katalogu ~/bin, a po uruchomieniu dowiązania symbolicznego otrzymuję "/ home".Więc przepraszam, moje rozwiązanie nie działa :( – maprihoda

+0

Zwróć też uwagę, że 'File.expand_path (" .. ", __FILE __)' jest po prostu zabawnym sposobem na powiedzenie 'File.dirname (__ FILE __)'. –

2

Spróbuj

require 'pathname' 
p File.dirname(Pathname.new(__FILE__).realpath) 
5

Aby uzyskać wszelkie ścieżki względem lokalizacji skryptu, zawsze korzystanie __dir__.

__dir__ to zwięzły sposób na powiedzenie File.dirname(File.realpath(__FILE__)). Jest dostępny w Ruby> = 2.0. On __dir__.

File.realpath(__FILE__) (lub Pathname#realpath) ma trzy zalety w porównaniu do File.readlink:

  • Rozszerza dowiązania gdziekolwiek w ścieżce. readlink rozwija tylko ścieżki, które są ostatnią częścią argumentu.
  • It (rekurencyjnie) usuwa dowiązania do dowiązania do ... readlink rozwiązuje tylko pierwszy poziom.
  • Nie trzeba sprawdzić, czy path jest dowiązaniem w ogóle. W ten sposób można upuścić if File.symlink?.

konsekwencji byłoby dobrze używać FOO_DIRECTORY = File.join(__dir__, '..', '..') lub FOO_DIRECTORY = File.dirname(File.dirname(__dir__))

Powiązane problemy