Make directory path
You are encouraged to solve this task according to the task description, using any language you may know.
Create a directory and any missing parents.
This task is named after the posix mkdir -p
command, and several libraries which implement the same behavior.
Please implement a function of a single path string (for example ./path/to/dir
) which has the above side-effect.
If the directory already exists, return successfully.
Ideally implementations will work equally well cross-platform (on windows, linux, and OS X).
It's likely that your language implements such a function as part of its standard library. If so, please also show how such a function would be implemented.
Go
The standard packages include os.MkdirAll which does exactly this (and its source is also available via that link). <lang go> os.MkdirAll("/tmp/some/path/to/dir", 0770)</lang>
Perl 6
There is a builtin function with the same name and it creates subdirectories by default.
<lang perl6>mkdir 'path/to/dir'</lang>
Python
<lang Python> from errno import EEXIST from os import mkdir, curdir from os.path import split, exists
def mkdirp(path, mode=0777):
head, tail = split(path) if not tail: head, tail = split(head) if head and tail and not exists(head): try: mkdirp(head, mode) except OSError as e: # be happy if someone already created the path if e.errno != EEXIST: raise if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists return try: mkdir(path, mode) except OSError as e: # be happy if someone already created the path if e.errno != EEXIST: raise
</lang>
Above is a modified version of the standard library's os.makedirs
, for pedagogical purposes. In practice, you would be more likely to use the standard library call:
<lang Python> def mkdirp(path):
try: os.makedirs(path) except OSError as exc: # Python >2.5 if exc.errno == errno.EEXIST and os.path.isdir(path): pass else: raise
</lang>
In Python3 this becomes even simpler:
<lang Python> def mkdirp(path):
os.makedirs(path, exist_ok=True)
</lang>
Racket
Uses `make-directory*` (NB the star -- that causes the intermediate directories to be produced).
Canonical documentation at http://docs.racket-lang.org/reference/Filesystem.html#%28def._%28%28lib._racket%2Ffile..rkt%29._make-directory*%29%29
Creates directory specified by _path_, creating intermediate
directories as necessary, and never failing if _path_ exists already.
<lang racket>#lang racket (define path-str "/tmp/woo/yay") (define path/..-str "/tmp/woo")
- clean up from a previous run
(when (directory-exists? path-str)
(delete-directory path-str) (delete-directory path/..-str))
- delete-directory/files could also be used -- but that requires goggles and rubber
- gloves to handle safely!
(define (report-path-exists)
(printf "~s exists (as a directory?):~a~%~s exists (as a directory?):~a~%~%" path/..-str (directory-exists? path/..-str) path-str (directory-exists? path-str)))
(report-path-exists)
- Really ... this is the only bit that matters!
(make-directory* path-str)
(report-path-exists)</lang>
- Output:
"/tmp/woo" exists (as a directory?):#f "/tmp/woo/yay" exists (as a directory?):#f "/tmp/woo" exists (as a directory?):#t "/tmp/woo/yay" exists (as a directory?):#t
JavaScript
Simplified version of the popular mkdirp library:
<lang Javascript>var path = require('path'); var fs = require('fs');
function mkdirp (p, cb) {
cb = cb || function () {}; p = path.resolve(p);
fs.mkdir(p, function (er) { if (!er) { return cb(null); } switch (er.code) { case 'ENOENT': // The directory doesn't exist. Make its parent and try again. mkdirp(path.dirname(p), function (er) { if (er) cb(er); else mkdirp(p, cb); }); break;
// In the case of any other error, something is borked. default: cb(er); break; } });
}</lang>
Ruby
<lang ruby>require 'fileutils' FileUtils.mkdir_p("path/to/dir") </lang> mkdir_p also takes an array of pathnames instead of a single pathname as an argument.
REXX
The following works with any modern (Microsoft) Windows ® and/or DOS.
Operating system note: all versions of Microsoft ® DOS require the use of a blackslash [\] instead of a forward slash [/].
Usage note: without the error messages being suppressed, the MKDIR command will issue an error message if the subdirectory (or its path) already exists.
<lang rexx>/*REXX program creates a directory and all its parent paths as necessary*/
trace off /*suppress possible warning msgs.*/
dPath = 'path\to\dir'
'MKDIR' dPath "2>nul" /*alias could be used: MD Dpath */
/*stick a fork in it, we're done.*/</lang>
UNIX Shell
<lang bash>function mkdirp() { mkdir -p "$1"; }</lang>
zkl
This is for Unix as zkl doesn't have a built in mkdir method. <lang zkl>System.cmd("mkdir -p ../foo/bar")</lang> The system error code is returned (0 in this case). <lang zkl>fcn mkdir(path) { System.cmd("mkdir -p "+path) }</lang>
- Output:
zkl: mkdir("../foo/bar") 0 zkl: mkdir("/foo/bar") mkdir: cannot create directory ‘/foo’: Permission denied 256