--- name: mkdir signature: 'mkdir FILENAME,MODE' since: 5.0 status: documented categories: ["Filehandles, files, directories"] --- ```{index} single: mkdir; Perl built-in ``` *[Filehandles, files, directories](../perlfunc-by-category)* # mkdir Create a single directory on the filesystem. `mkdir` asks the operating system to create the directory named by `FILENAME`, with permission bits given by `MODE` (further restricted by the process [`umask`](umask)). It creates exactly **one** directory — every parent component in `FILENAME` must already exist. For recursive creation, reach for `File::Path::make_path` instead. ## Synopsis ```perl mkdir FILENAME, MODE mkdir FILENAME mkdir ``` ## What you get back `1` on success, `0` on failure with [`$!`](../perlvar) set to the system errno. Unlike most I/O primitives, the failure value is a plain false `0`, not [`undef`](undef) — check the return value, then consult [`$!`](../perlvar) for the reason: ```perl mkdir $path, 0755 or die "mkdir $path failed: $!"; ``` ## Default arguments Both arguments default: - `MODE` defaults to `0777`. The kernel masks the supplied mode with the current process [`umask`](umask), so the directory's effective mode is `MODE & ~umask`. A typical `umask` of `022` turns the default `0777` into `0755` on disk. - `FILENAME` defaults to [`$_`](../perlvar). Bare `mkdir;` inside a loop over pathnames creates each in turn: ```perl mkdir for qw(logs cache tmp); ``` Pass `MODE` explicitly whenever the directory should be private (mail spools, key stores, session directories). Otherwise prefer a permissive `MODE` and let the user's `umask` narrow it — the [`umask`](umask) page discusses the trade-off in detail. Setting bits outside the permission range (e.g. setuid/setgid/sticky) yields implementation-defined behaviour per POSIX 1003.1-2008. ## Global state it touches - Sets [`$!`](../perlvar) (errno) on failure; leaves it untouched on success. - Reads `FILENAME` from [`$_`](../perlvar) when called with no arguments. - The effective permission bits depend on the process [`umask`](umask). ## Examples Create a directory with an explicit mode: ```perl mkdir "build", 0755 or die "mkdir build: $!"; ``` Create it only if missing, without treating "already there" as an error: ```perl use Errno qw(EEXIST); unless (mkdir "cache", 0700) { die "mkdir cache: $!" unless $! == EEXIST; } ``` Private directory — do not let `umask` widen it: ```perl mkdir "$ENV{HOME}/.secrets", 0700 or die "mkdir secrets: $!"; ``` Bare form over a list, using [`$_`](../perlvar) as the filename: ```perl for (qw(a b c)) { mkdir or warn "mkdir $_: $!"; } ``` Recursive creation is **not** `mkdir`'s job — use `File::Path`: ```perl use File::Path qw(make_path); make_path("var/log/app/2026", { mode => 0755 }) or die "make_path failed: $!"; ``` ## Edge cases - **Parent must exist**. `mkdir "a/b/c"` fails with `ENOENT` if `a/b` is missing. Use `File::Path::make_path` for deep paths. - **Target already exists**. Fails with `EEXIST`, regardless of whether the existing entry is a directory, file, or symlink. Check [`$!`](../perlvar) against `Errno::EEXIST` when "already there" is acceptable. - **Trailing slashes**. POSIX 1003.1-1996 allows any number of trailing slashes; Perl strips them before the syscall so that filesystems which reject `"foo/"` still behave consistently. - **Permission mismatch**. `MODE` is masked by [`umask`](umask). If you need an exact mode on disk, either save and restore the umask, or [`chmod`](chmod) the directory after creation: ```perl mkdir $dir, 0700 or die $!; chmod 0700, $dir; # defeat any umask surprises ``` - **`MODE` omitted entirely**. `mkdir $path` is `mkdir $path, 0777` — still masked by `umask`, so the on-disk mode is typically `0755`, not `0777`. - **Non-permission bits in `MODE`**. Setuid / setgid / sticky bits on a `mkdir` call have implementation-defined results. Set them with a follow-up [`chmod`](chmod) if you need them. - **Read-only filesystem or missing write permission on the parent** fails with `EROFS` or `EACCES` respectively. [`$!`](../perlvar) discriminates. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`rmdir`](rmdir) — remove an empty directory; the inverse operation - [`chmod`](chmod) — adjust permission bits after creation when `umask` would otherwise narrow them - [`umask`](umask) — the mask that silently restricts every `mkdir MODE` - [`stat`](stat) — inspect an existing path's type and mode, e.g. to distinguish "already a directory" from "exists as a file" - `File::Path::make_path` — recursive directory creation; the right tool when intermediate parents may not exist