How to check if a directory/file/symlink exists with one command in Ruby
Asked Answered
R

3

88

Is there a single way of detecting if a directory/file/symlink/etc. entity (more generalized) exists?

I need a single function because I need to check an array of paths that could be directories, files or symlinks. I know File.exists?"file_path" works for directories and files but not for symlinks (which is File.symlink?"symlink_path").

Riffe answered 4/2, 2011 at 11:39 Comment(2)
What version of Ruby are you using? File.exists? works for symlinks for me in Ruby 1.9.2 in OS X 10.6.6Rewire
To clarify: for symlinks, you're asking for something that returns true if the symlink exists, regardless of whether it can be ultimately resolved to a non-symlink. I.e. it should return true for broken links as well. File.exists? will only return true for a symlink that's not broken.Hogshead
C
156

The standard File module has the usual file tests available:

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

You should be able to find what you want there.


OP: "Thanks but I need all three true or false"

Obviously not. Ok, try something like:

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
Cascarilla answered 4/2, 2011 at 14:3 Comment(4)
I would advise against doing raw string concatenation (ENV['HOME'] + '/.bashrc') which may not work cross-platform. You should use Ruby File joins and also why not start from Rails.root if you are using Rails. File.exists?(Rails.root.join('db', 'my_seeds.csv')Copestone
It's guaranteed to not work cross-platform since Windows doesn't know about Bash, and hence, about .bashrc. But it'd work on a *nix-based platform. The use of / isn't the issue though, since Ruby's IO automatically converts from forward slashes to back slashes on Windows.Cascarilla
Maybe that was true in December 2016, but Windows definitely does know about Bash these days. :-) I can type bash into the Start Menu, and in the resulting console window, cat ~/.bashrc produces output. ¯\_(ツ)_/¯Madancy
The answer by Cyril is unfortunately not fully correct - string concatenation DOES work on windows do for "File.exist?" checks, as the Tin Man already pointed out. I only added this comment here to confirm it.Burkley
B
15

Why not define your own function File.exists?(path) or File.symlink?(path) and use that?

Bertrando answered 4/2, 2011 at 11:52 Comment(8)
Of course I can do that, but I would like a way already implemented that can check both of them. I mean to check if at that path there is 'something'.Riffe
@Clawsy I think you're missing Gintautas's point: you're a programmer - if the function you need doesn't exist, you can create it.Puerperal
No, I am not missing the point :). I understand perfectly. I just want to add as little code as possible to my application. In my case, it is better (for software engineering matters) if I find a method like that. If not, that is... I make one, no problem. I just wanted to know if there is a predefined one. I am not lazy, it's just inserting a code in a HUGE application that must be very well taken care of. I just wanted to know that.... because I don't want to repeat myself. (DRY - Do Not Repeat Yourself, from Pragmatic Programmer book :D).Riffe
Why reinvent the wheel when it's already part of the language?Cascarilla
I find it very useful not to obsess about detail too much in programming. If you know a straightforward and simple way to solve a problem, just do it. If you find a better way some time later, you can always go back and fix. Defining a new function is a no-brainer in this situation.Bertrando
But, the functionality is already built into the language and is simple to use. It then becomes a case of reading to see what is available and adding the call. Writing code to implement functionality that already exists just because you didn't take the time to read an RDoc that comes with the language... just doesn't add up to me. By that logic you could end up rewriting the standard library.Cascarilla
This method must exist in the core somewhere! I shall continue to search for it until it magically appears, or until the end of days, whichever comes first. It's worth it to save one extra method call.Lewis
Use File.exist? instead of File.exists? as this is deprecated in ruby 2.2.0: ruby-doc.org/core-2.2.0/File.html#method-c-exists-3FParish
L
-1

Just File.exist? on it's own will take care of all of the above for you

Lenna answered 16/11, 2021 at 4:21 Comment(1)
As it says in the question, it doesn't work for symlinks.Orvie

© 2022 - 2024 — McMap. All rights reserved.