Check if directory is empty in Ruby
Solution 1
Ruby now has Dir.empty?
, making this trivially easy:
Dir.empty?('your_directory') # => (true|false)
In Rubies prior to 2.4.0 you can just get a list of the entries and see for yourself whether or not it's empty (accounting for "." and ".."). See the docs.
(Dir.entries('your_directory') - %w{ . .. }).empty?
# or using glob, which doesn't match hidden files (like . and ..)
Dir['your_directory/*'].empty?
Update: the first method above used to use a regex; now it doesn't (obviously). Comments below mostly apply to the former (regex) version.
Solution 2
As of Ruby 2.4.0, there is Dir.empty?
Dir.empty?('/') # => false
Solution 3
You can use entries to see all files and folders in a directory:
Dir.entries('directory')
=> ['.', '..', 'file.rb', '.git']
Dir.entries('directory').size <= 2 # Check if empty with no files or folders.
You can also search for files only using glob:
Dir.glob('directory/{*,.*}')
=> ['file.rb', '.git']
Dir.glob('directory/{*,.*}').empty? # Check if empty with no files.
Solution 4
An empty directory should only have two links (. and ..). On OSX this works:
File.stat('directory').nlink == 2
...but does not work on Linux or Cygwin. (Thanks @DamianNowak) Adapting Pan's answer:
Dir.entries('directory').size == 2
should work.
Solution 5
Not straightforward but works perfect in *nix kind of systems.
Dir.entries(directory_path) == ['.', '..']
Mark Szymanski
Updated on August 27, 2020Comments
-
Mark Szymanski almost 4 years
How can I check to see if a directory is empty or not in Ruby? Is there something like:
Dir.exists?("directory")
(I know that that function doesn't exist.)
-
Mark Szymanski over 13 yearsThe first one gave me errors, but the second worked perfectly. Thanks!
-
coreyward over 13 years@Mark Szymanski: Ahh yeah I wrapped the block in parentheses. Fixed.
-
Pan Thomakos over 13 yearsThe first command will also ignore hidden files, like .git though.
-
coreyward over 13 years@Pan Thomakos: No it won't. The second will, but the first only rejects filenames consisting of only dots.
-
mu is too short over 13 yearsBut
...
is a valid filename (as is....
, ...), I think you'd be better off with an explicitx == '.' || x == '..'
check than your regex. True,...
is a pathological case but saying exactly what you mean is a good idea. -
coreyward over 13 years@mu I thought about that, but figured it wasn't too important since it's an edge case and the second method sidesteps the matter all together. Still, though, I'll update just to make sure it doesn't cause someone trouble in the future.
-
mu is too short over 13 yearsBut
Dir.glob('directory/*')
will leave out files that begin with.
, for example.profile
or.git
. -
Pan Thomakos over 13 years@(mu is too short) - You're correct. I updated my regexp to include hidden files as well.
-
Ben Flynn over 12 yearsDir.glob('directory/{,.}') captures "." and ".." so empty? will always return false.
-
Nowaker about 12 years
nlink
checks for number of subdirectories, which is wrong.size
should be checked. -
Ben Flynn about 12 years@DamianNowak Not so, try irb File.stat('.').nlink ruby-doc.org/core-1.9.3/File/Stat.html#method-i-nlink
-
Ben Flynn about 12 yearsMust be OS specific? pastie.org/4128791 I am using OSX Lion (11.4.0 Darwin)
-
Ben Flynn about 12 yearsNoticed I am using ruby 1.8.7. "size" returns a number of bytes I believe and therefore does not work on OSX. If you can confirm your OS and Ruby version I'd suggest adding that to the existing answer.
-
Ben Flynn about 12 years