I want to store a file as /a/b/c/d.txt, but I do not know if any of these directories exist and need to recursively create them if necessary. How can one do this in ruby?
Asked
Active
Viewed 4.4k times
6 Answers
210
Use mkdir_p
:
FileUtils.mkdir_p '/a/b/c'
The _p
is a unix holdover for parent/path you can also use the alias mkpath
if that makes more sense for you.
FileUtils.mkpath '/a/b/c'
In Ruby 1.9 FileUtils was removed from the core, so you'll have to require 'fileutils'
.

Harmon Wood
- 2,977
- 1
- 15
- 12
-
9+1. `FileUtils` and `Pathname` are probably *the* most important tools for Ruby shell scripting. – Jörg W Mittag Sep 10 '10 at 17:41
23
Use mkdir_p to create directory recursively
path = "/tmp/a/b/c"
FileUtils.mkdir_p(path) unless File.exists?(path)

ferbass
- 859
- 5
- 17
6
If you are running on unixy machines, don't forget you can always run a shell command under ruby by placing it in backticks.
`mkdir -p /a/b/c`

Matthew Schinckel
- 35,041
- 6
- 86
- 121
-
-
2Poping system command into sub-process is not the best idea. It's better to do it with the Ruby standard library to get error handling, check the result, etc. – noraj Oct 07 '19 at 21:31
5
Pathname to the rescue!
Pathname('/a/b/c/d.txt').dirname.mkpath

Vadym Tyemirov
- 8,288
- 4
- 42
- 38
-
This is less intuitive than the accepted answer. Also the doc for the method forward to FileUtils https://ruby-doc.org/stdlib-2.6.5/libdoc/pathname/rdoc/Pathname.html#method-i-mkpath – noraj Oct 07 '19 at 21:34
-
1The question is: "I want to store a file as /a/b/c/d.txt, but I do not know if any of these directories exist". My solution allows to use the existing file path ('/a/b/c/d.txt'), and, without separate parsing, create all the folders. – Vadym Tyemirov Oct 09 '19 at 04:47
-
You mean this allow to do `FileUtils.mkdir_p '/a/b/c'` + create `d.txt` at the same time? – noraj Oct 09 '19 at 18:22
-
1Nope, instead it allows `Pathname('/a/b/c/d.txt').dirname.mkpath` and `File.write('/a/b/c/d.txt', content)` without `filename = '/a/b/c/d.txt'.rpartition('/').last` and the rest of the parsing – Vadym Tyemirov Oct 10 '19 at 20:18
3
require 'ftools'

einarmagnus
- 3,507
- 1
- 21
- 31
-
1Thanks for the pointer! The docs seem to prefer FileUtils.mkdir_p, so I took that... – Jan Sep 10 '10 at 15:49
-
This is only an alias for `mkdir_p` and `mkpath` https://ruby-doc.org/stdlib-2.6.5/libdoc/fileutils/rdoc/FileUtils.html#method-c-mkdir_p – noraj Oct 07 '19 at 21:30
0
You could also use your own logic
def self.create_dir_if_not_exists(path)
recursive = path.split('/')
directory = ''
recursive.each do |sub_directory|
directory += sub_directory + '/'
Dir.mkdir(directory) unless (File.directory? directory)
end
end
So if path is 'tmp/a/b/c' if 'tmp' doesn't exist 'tmp' gets created, then 'tmp/a/' and so on and so forth.

kamal patwa
- 429
- 1
- 4
- 9