Check if directory is empty in Ruby

21,294

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) == ['.', '..']
Share:
21,294
Mark Szymanski
Author by

Mark Szymanski

Updated on August 27, 2020

Comments

  • Mark Szymanski
    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
    Mark Szymanski over 13 years
    The first one gave me errors, but the second worked perfectly. Thanks!
  • coreyward
    coreyward over 13 years
    @Mark Szymanski: Ahh yeah I wrapped the block in parentheses. Fixed.
  • Pan Thomakos
    Pan Thomakos over 13 years
    The first command will also ignore hidden files, like .git though.
  • coreyward
    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
    mu is too short over 13 years
    But ... is a valid filename (as is ...., ...), I think you'd be better off with an explicit x == '.' || x == '..' check than your regex. True, ... is a pathological case but saying exactly what you mean is a good idea.
  • coreyward
    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
    mu is too short over 13 years
    But Dir.glob('directory/*') will leave out files that begin with ., for example .profile or .git.
  • Pan Thomakos
    Pan Thomakos over 13 years
    @(mu is too short) - You're correct. I updated my regexp to include hidden files as well.
  • Ben Flynn
    Ben Flynn over 12 years
    Dir.glob('directory/{,.}') captures "." and ".." so empty? will always return false.
  • Nowaker
    Nowaker about 12 years
    nlink checks for number of subdirectories, which is wrong. size should be checked.
  • Ben Flynn
    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
    Ben Flynn about 12 years
    Must be OS specific? pastie.org/4128791 I am using OSX Lion (11.4.0 Darwin)
  • Ben Flynn
    Ben Flynn about 12 years
    Noticed 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
    Ben Flynn about 12 years