How to check if a given directory exists in Ruby
If it matters whether the file you're looking for is a directory and not just a file, you could use File.directory?
or Dir.exist?
. This will return true only if the file exists and is a directory.
As an aside, a more idiomatic way to write the method would be to take advantage of the fact that Ruby automatically returns the result of the last expression inside the method. Thus, you could write it like this:
def directory_exists?(directory)
File.directory?(directory)
end
Note that using a method is not necessary in the present case.
Check if path is a directory path (it might not exist)
TL;DR
If the Pathname isn't on the filesystem already, it's just a name. Its type (e.g. file or directory) isn't fixed until you create a filesystem object with it. So, I recommend either unambiguously constructing each directory Pathname with a trailing separator, or using the Pathname to create the file or directory with the relevant methods for its intended type.
Testing Pathname Objects with Trailing Directory Separator
If you're using the Pathname module, the Pathname doesn't have to exist to be used. In such cases, it's useful to note that the Ruby engine converts forward slashes into backslashes when on Windows, so the following constructed pathnames should work on Windows, Linux, MacOS, and Unix:
Pathname('/some/path/').to_s.end_with? ?/
#=> true
Pathname('C:/some/path/').to_s.end_with? ?/
#=> true
However, if your Pathname is constructed manually or programmatically without being read in from the filesystem or using File#join, you may need to use a character class to check for both *nix and Windows trailing separators. For example:
require 'pathname'
%w[ /some/path/ C:\\some\\path\\ ].map do |path|
Pathname(path).to_s.match? %r![/\\]\z!
end
#=> [true, true]
Using Method to Set Filesystem Object Type
If you construct a path without a trailing directory separator but the directory doesn't actually exist in the filesystem, then you can't determine just from the name whether it's supposed to be a file or directory. A Pathname is really just a special type of String object. The documentation explicitly states (emphasis mine):
Pathname represents the name of a file or directory on the filesystem, but not the file itself.
That being the case, your best bet is to modify your Pathname constructor to ensure that you're building names with trailing separators in the first place. If you can't or won't do that, you will have to leave it up to your filesystem writing code to explicitly call an appropriate method explicitly on the expected filesystem object. For example:
require 'pathname'
require 'fileutils'
path = Pathname '/tmp/foo'
# ensure file or directory doesn't already exist
path.rmtree
# use path as file
FileUtils.touch path
path.file?
#=> true
# remove path before next test
path.unlink
# use path as directory
path.mkpath
path.directory?
#=> true
As you can see, a Pathname without a trailing (back)slash can be used for both files and directories, depending on how you use it.
Can't test if directory already exists from within Fastlane with Ruby
LOL Well, I discovered my issue. I didn't realize that I had to include the entire path to each of these statements, since I'm using Dir.foreach
to iterate over part of the filesystem; the updated syntax is:
Dir.foreach(save_path) do |dir|
next if dir == '.' or dir == '..'
if (File.directory?("#{save_path}#{dir}"))
begin
FileUtils.mkdir_p("./#{save_path}#{dir}/images")
rescue StandardError => e
UI.message("Failed to make directory ./#{save_path}#{dir}/images: #{e.to_s}")
return
end
end
end
This is versus File.directory?("#{dir}")
in that if statement. I thought that the Ruby Dir
and FileUtil
libraries would look relative to the current directory for the remainder of the path.
How to check if a directory/file/symlink exists with one command in Ruby
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
How to check if a directory exists in a Chef recipe NOT_IF?
I would suggest checking out out the ark cookbook for handling remote archive packages.
include_recipe "ark"
ark 'RevoMath' do
url 'https://mran.revolutionanalytics.com/install/RevoMath-1.0.1.tar.gz'
end
Which will install the tar package content into the /usr/local/RevoMath-1.0.1 directory. These defaults can be overridden.
How to check whether a File exists
File.exist? File.expand_path "~/dlds/some_file.ics"
Check if file/folder is in a subdirectory in Ruby
I hope I understood your question correct.
An example:
require 'pathname'
A = '/usr/xxx/a/b/c.txt'
path = Pathname.new(A)
[
'/usr/xxx/a/b',
'/usr/yyy/a/b',
].each{|b|
if path.fnmatch?(File.join(b,'**'))
puts "%s is in %s" % [A,b]
else
puts "%s is not in %s" % [A,b]
end
}
Result:
/usr/xxx/a/b/c.txt is in /usr/xxx/a/b
/usr/xxx/a/b/c.txt is not in /usr/yyy/a/b
The solution uses the class Pathname. An advantage of it: Pathname represents the name of a file or directory on the filesystem, but not the file itself. So you can make your test without a read access to the file.
The test itself is made with Pathname#fnmatch?
and a glob-pattern File.join(path,'**')
(**
means all sub-directories).
If you need it more often, you could extend Pathname
:
require 'pathname'
class Pathname
def is_underneath?(path)
return self.fnmatch?(File.join(path,'**'))
end
end
A = '/usr/xxx/a/b/c.txt'
path = Pathname.new(A)
[
'/usr/xxx/a/b',
'/usr/yyy/a/b',
].each{|b|
if path.is_underneath?(b)
puts "%s is in %s" % [A,b]
else
puts "%s is not in %s" % [A,b]
end
}
To handle absolute/relative pathes it may help to expand the pathes like in (sorry, this is untested).
class Pathname
def is_underneath?(path)
return self.expand_path.fnmatch?(File.expand_path(File.join(path,'**')))
end
end
Check if directory is empty in Ruby
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.
Check if some files in array exist in directory
This is my solution after numerous attempts:
origin_files = ['test1.rb', 'test2.rb']
dir_path = "C:\\Test"
ruby_block "Rename file" do
block do
for filename in origin_files
newname = filename.split(".")[0] + '.origin'
if ::File.exist?("#{dir_path}\\#{newname}")
Chef::Log.info("### Your file: #{newname} already renamed ###")
else
::File.rename("#{dir_path}\\#{filename}", "#{dir_path}\\#{newname}")
end
end
end
end
Related Topics
How to Remove Permission Denied @ Rb_Sysopen - Gem Install Error
How to Uninstall Ruby on Rails on MAC Os X
How to Automate Chrome Request Blocking Using Selenium-Webdriver for Ruby
Set Attribute Dynamically of Ruby Object
Why Does Array.Slice Behave Differently for (Length, N)
How to Dynamically Alter Inheritance in Ruby
Add "# Coding: Utf-8" to All Files
How to Iterate Activerecord Attributes, Including Attr_Accessor Methods
Dynamically Set Local Variables in Ruby
Change the Binding of a Proc in Ruby
How to Debug in Rubymine 4.5 Using Ruby 1.9.3
Using Ruby Convert Numbers to Words
Project Euler 1:Find the Sum of All the Multiples of 3 or 5 Below 1000
Errno::Econnrefused: Connection Refused - Connect(2) for Action Mailer
Understanding How Establish_Connection Works in Activerecord