Cómo verificar si existe un directorio / archivo / enlace simbólico con un comando en Ruby

81

¿Existe una única forma de detectar si un directorio / archivo / enlace simbólico / etc. entidad (más generalizada) existe?

Necesito una sola función porque necesito verificar una serie de rutas que podrían ser directorios, archivos o enlaces simbólicos. Sé que File.exists?"file_path"funciona para directorios y archivos, pero no para enlaces simbólicos (que es File.symlink?"symlink_path").

claudiut
fuente
1
¿Qué versión de Ruby estás usando? ¿El archivo existe? funciona para enlaces simbólicos para mí en Ruby 1.9.2 en OS X 10.6.6
1
Para aclarar: para los enlaces simbólicos, está pidiendo algo que devuelva truesi el enlace simbólico existe, independientemente de si finalmente se puede resolver como un enlace no simbólico. Es decir, también debería regresar truepor enlaces rotos. File.exists?solo regresará truepara un enlace simbólico que no esté roto.
Kelvin

Respuestas:

146

El módulo de archivo estándar tiene disponibles las pruebas de archivo habituales :

RUBY_VERSION # => "1.9.2"
bashrc = ENV['HOME'] + '/.bashrc'
File.exist?(bashrc) # => true
File.file?(bashrc)  # => true
File.directory?(bashrc) # => false

Debería poder encontrar lo que busca allí.


OP: "Gracias, pero necesito los tres verdaderos o falsos"

Obviamente no. Ok, prueba algo como:

def file_dir_or_symlink_exists?(path_to_file)
  File.exist?(path_to_file) || File.symlink?(path_to_file)
end

file_dir_or_symlink_exists?(bashrc)                            # => true
file_dir_or_symlink_exists?('/Users')                          # => true
file_dir_or_symlink_exists?('/usr/bin/ruby')                   # => true
file_dir_or_symlink_exists?('some/bogus/path/to/a/black/hole') # => false
el hombre de hojalata
fuente
1
Aconsejaría no hacer una concatenación de cadenas sin formato ( ENV['HOME'] + '/.bashrc') que puede no funcionar en varias plataformas. Debería usar Ruby File joins y también por qué no comenzar desde Rails.rootsi está usando Rails. File.exists?(Rails.root.join('db', 'my_seeds.csv')
Cyril Duchon-Doris
2
Está garantizado que no funcionará en varias plataformas, ya que Windows no conoce Bash y, por lo tanto, no conoce .bashrc. Pero funcionaría en una plataforma basada en * nix. Sin /embargo, el uso de no es el problema, ya que Ruby IO se convierte automáticamente de barras diagonales a barras diagonales inversas en Windows .
The Tin Man
Tal vez eso era cierto en diciembre de 2016, pero Windows definitivamente no sabe acerca de Bash en estos días. :-) Puedo escribir bashen el menú Inicio, y en la ventana de la consola resultante, cat ~/.bashrcproduce una salida. ¯ \ _ (ツ) _ / ¯
Jonathan Gilbert
Desafortunadamente, la respuesta de Cyril no es del todo correcta: la concatenación de cadenas FUNCIONA en Windows para "File.exist?" cheques, como ya señaló el Hombre de Hojalata. Solo agregué este comentario aquí para confirmarlo.
shevy
13

¿Por qué no definir su propia función File.exists?(path) or File.symlink?(path)y utilizarla?

Gintautas Miliauskas
fuente
2
@Clawsy Creo que te estás perdiendo el punto de Gintautas: eres un programador, si la función que necesitas no existe, puedes crearla.
Telemachus
4
¿Por qué reinventar la rueda cuando ya forma parte del lenguaje?
The Tin Man
11
Me resulta muy útil no obsesionarme demasiado con los detalles en la programación. Si conoce una forma sencilla y directa de resolver un problema, simplemente hágalo. Si encuentra una mejor manera más tarde, siempre puede volver atrás y arreglarlo. Definir una nueva función es una obviedad en esta situación.
Gintautas Miliauskas
5
Pero la funcionalidad ya está integrada en el lenguaje y es fácil de usar. Luego se convierte en un caso de lectura para ver qué está disponible y agregar la llamada. Escribir código para implementar una funcionalidad que ya existe solo porque no se tomó el tiempo para leer un RDoc que viene con el lenguaje ... simplemente no me suma. Con esa lógica, podría terminar reescribiendo la biblioteca estándar.
The Tin Man
2
¿Usar File.exist? en lugar de File.exists? ya que está obsoleto en ruby ​​2.2.0: ruby-doc.org/core-2.2.0/File.html#method-c-exists-3F
atw