2011-12-16 11 views
14

Tengo un script de Ruby con ruta /foo/bar/gazook/script.rb. También creé un enlace simbólico a él en $HOME/bin.Después de enlazar simbólicamente un archivo, ¿cómo obtengo la ruta del archivo original en Ruby?

Ahora, quiero que mi script de Ruby acceda a algún otro archivo en el directorio /foo, y para mantener las rutas relativas, tengo una variable FOO_DIRECTORY = File.expand_path(File.dirname(__FILE__) + "/../../") en mi script.

El problema es que si ejecuto mi script desde su enlace simbólico, este directorio relativo es incorrecto (ya que supongo que se está expandiendo desde una ubicación diferente).

¿Cómo puedo solucionar esto? ¿Hay alguna manera además de usar un camino absoluto?

Respuesta

10

Puede utilizar File.readlink para resolver un enlace simbólico pero usted desee comprobar File.symlink? primero.

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

A continuación, se puede trabajar con path en lugar de __FILE__. Es posible que desee utilizar $0 en lugar de __FILE__, __FILE__ es el nombre de archivo actual, mientras que $0 es el nombre del script actual.

+3

Para una solución más general, debe resolver los enlaces simbólicos en un bucle, porque un enlace simbólico puede apuntar a otro. Además, debe verificar cada parte de la ruta: 'bin' puede ser una symlink, también. Yo recomendaría 'File.realpath'. – hagello

-1

Prueba esto:

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

I a decir que el problema es que el archivo de enlace simbólico es interpretar File.dirname(__FILE__)

+0

'expand_path' no resuelve los enlaces simbólicos y especifique el' dir_string' no ayudará a: [ "Las rutas relativas son referenciados desde el directorio de trabajo actual el proceso a menos que se indique dir_string, en cuyo caso se usará como punto de partida. "] (http://ruby-doc.org/core-1.9.3/File.html#method-c-expand_path). Además, el segundo argumento para 'expand_path' debe ser un * directorio *, no un nombre de archivo. –

+0

OK, creé un archivo de prueba, un enlace simbólico en mi directorio ~/bin, y cuando ejecuto el enlace simbólico, obtengo "/ home".Así que me disculpo, mi solución no funciona :( – maprihoda

+0

Y también notamos que 'File.expand_path (" .. ", __FILE __)' es solo una forma divertida de decir 'File.dirname (__ FILE __)'. –

2

probar este

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

Para obtener cualquier ruta relativa a la ubicación de su script, siempre uso __dir__.

__dir__ es una forma concisa de decir File.dirname(File.realpath(__FILE__)). Está disponible en Ruby> = 2.0. On __dir__.

File.realpath(__FILE__) (o Pathname#realpath) tiene tres ventajas en comparación con File.readlink:

  • Se expande enlaces simbólicos en cualquier lugar en la ruta. readlink solo expande las rutas que son la última parte del argumento.
  • Resuelve (de manera recursiva) los enlaces simbólicos a los enlaces simbólicos a ... readlink resuelve solo el primer nivel.
  • No es necesario comprobar si path es un enlace simbólico. Por lo tanto, puede soltar el if File.symlink?.

En consecuencia, sería bueno utilizar FOO_DIRECTORY = File.join(__dir__, '..', '..') o FOO_DIRECTORY = File.dirname(File.dirname(__dir__))

Cuestiones relacionadas