2011-12-16 7 views
14

Ho uno script Ruby con il percorso /foo/bar/gazook/script.rb. Ho anche creato un collegamento simbolico ad esso in $HOME/bin.Dopo aver collegato un file simbolico, come faccio a ottenere il percorso del file originale in Ruby?

Ora, voglio che il mio script Ruby acceda ad altri file nella directory /foo, e per mantenere i percorsi relativi, ho una variabile FOO_DIRECTORY = File.expand_path(File.dirname(__FILE__) + "/../../") nel mio script.

Il problema è che se eseguo il mio script dal suo collegamento simbolico, questa directory relativa è errata (poiché immagino che si espanda da una posizione diversa).

Come posso risolvere questo problema? C'è un modo oltre all'utilizzo di un percorso assoluto?

risposta

10

È possibile utilizzare File.readlink per risolvere un collegamento simbolico, ma ti consigliamo di controllare File.symlink? prima.

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

Poi si può lavorare con path invece di __FILE__. È possibile utilizzare $0 anziché __FILE__, mentre __FILE__ è il nome file corrente mentre $0 è il nome dello script corrente.

+3

Per una soluzione più generale, è necessario risolvere i collegamenti simbolici in un ciclo, poiché un collegamento simbolico può puntare a un altro. Inoltre, è necessario controllare ogni parte del percorso: 'bin' può essere un link simbolico, consiglierei 'File.realpath'. – hagello

-1

Prova questa:

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

io di dire che il problema è che il file link simbolico sta interpretando File.dirname(__FILE__)

+0

'expand_path' non risolve i collegamenti simbolici e specificare il' dir_string' non aiuterà: [ "I percorsi relativi sono tratti dalle directory di lavoro corrente di il processo a meno che non venga fornito dir_string, nel qual caso verrà usato come punto di partenza. "] (http://ruby-doc.org/core-1.9.3/File.html#method-c-expand_path). Inoltre, il secondo argomento di 'expand_path' dovrebbe essere una * directory *, non un nome di file. –

+0

OK, ho creato un file di test, un link simbolico nella mia directory ~/bin, e quando eseguo il collegamento simbolico, ottengo "/ home".Quindi mi scuso, la mia soluzione non funziona :( – maprihoda

+0

E anche notare che 'File.expand_path (" .. ", __FILE __)' è solo un modo divertente di dire 'File.dirname (__ FILE __)'. –

2

Prova questa

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

Per ottenere qualsiasi percorso relativo alla posizione del vostro scritto, sempre uso __dir__.

__dir__ è un modo conciso per dire File.dirname(File.realpath(__FILE__)). È disponibile in Ruby> = 2.0. On __dir__.

File.realpath(__FILE__) (o Pathname#realpath) presenta tre vantaggi rispetto al File.readlink:

  • Si espande simbolici ovunque nel percorso. readlink espande solo i percorsi che rappresentano l'ultima parte dell'argomento.
  • Esso (in modo ricorsivo) risolve i collegamenti simbolici ai collegamenti simbolici a ... readlink risolve solo il primo livello.
  • Non è necessario verificare se path è un collegamento simbolico. Quindi puoi lasciare lo if File.symlink?.

conseguenza sarebbe bene utilizzare FOO_DIRECTORY = File.join(__dir__, '..', '..') o FOO_DIRECTORY = File.dirname(File.dirname(__dir__))

Problemi correlati