Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Errno::ENOENT: No such file or directory ruby

Tags:

ruby

I am getting the following error:

"Errno::ENOENT: No such file or directory"

when I try to download a file into a directory that does not exist.

For example:

ftp = Net::FTP.new('example.com')
ftp.login
files = ftp.chdir('pub/lang/ruby/contrib')
files = ftp.list('n*')
ftp.getbinaryfile('nif.rb-0.91.gz', 'pub/lang/ruby/contrib/nif.gz', 1024)
ftp.close

However, for many of the files I will be downloading, the full directory path will not exist. For example, until the first file creates pub, it won't exist and this goes for lang/ruby/contrib too.

Is there a method that can check if directories exist and if not create them? I know that there is exist?, but that looks to reference files and it does not create the full path. I figure I need some recursive method to traverse down the folder structure until it hits the filename.

EDIT: mkdir_p seems to be exactly the solution I need.

However, when I use a path of "/a/b/c" I noticed that FileUtils.mkdir_p(File.dirname(localdir)) returns an error: Errno::EACCES: Permission denied - /a

If I remove the "/" in front manually it works. What is causing this? What is the best solution for resolving the error? should I just use the following?

 path="/a/b/c"
 if path[0]="/"
    path=path[1..-1]
 end

However, I feel like this is just a hack.

like image 821
user2012677 Avatar asked Mar 25 '13 00:03

user2012677


4 Answers

You can't save to a non-existing path. As the developer you're responsible to make sure your destination paths exist prior to trying to save the file.

Ruby has methods that let you check for the existence a file or directory:

  • File.exist?('path/to/file')
  • File.file?('path/to/file')
  • File.directory?('path/to/file')
  • Dir.directory?('path/to/dir')
  • Dir.mkdir('path/to/dir')
  • FileUtils.makedirs('path/to/dir')

FileUtils.makedirs() is an alias to mkpath, and mkdir_p. I prefer makedirs because it's a mnemonic.

These will also be useful:

  • Dir.chdir('path/to/dir')
  • FileUtils.chdir('path/to/dir')

Between those two I prefer Dir.chdir, because it takes a block. Any actions that occur inside that block happen in the directory you changed to. At exit, the directory reverts to what it was previously.

like image 102
the Tin Man Avatar answered Oct 15 '22 14:10

the Tin Man


The analog of *nix mkdir -p, mkdir_p, is what you need, which was provided in the other two answers, but I didn't see anyone address your edit about permissions.

The solution is the user invoking your script requires write permission on the root directory.

The path, "/a/b/c", is addressing the root path ("/"). This is typically only write accessible to the root user or a user that has sudo access.

When you modified the path to remove the leading "/", you told mkdir_p to create the directories "a/b/c" relative to the current working directory instead of relative to the root directory. The reason the modified version works is because the user invoking your ruby script has write permission on the current working directory.

As a personal aside, if consumers of your script are providing the path input, then you probably don't want to remove leading slashes as that can create files/directories in a drastically different place from where the user expects...unless that is the purpose of your program, but make that clear up front.

References:

  • *nix-style permissions
  • sudo
like image 27
Jim Ford Avatar answered Oct 15 '22 12:10

Jim Ford


I got here because I had gem installed but the file was not installed on the machine. In my case, I had gem espeak-ruby gem was installed but it was not installed on my mac so I installed that with simple brew install espeak command and restarted the server. My recommendation to you us make sure everything is installed properly.

like image 2
gsumk Avatar answered Oct 15 '22 12:10

gsumk


In the fileutils module you can use mkdir_p which is similar to the mkdir -p command which creates the full path if it doesn't already exist.

like image 1
Jorge Israel Peña Avatar answered Oct 15 '22 12:10

Jorge Israel Peña