9.2 mkdir: Creating Directories and -p for Nested Paths
Right, let’s talk about making directories. It’s one of those things you do so often you stop thinking about it, which is exactly when you’ll make a spectacularly silly mistake. I’ve seen a senior engineer accidentally run mkdir node_modules in his home directory. Don’t be that person. Let’s get this right.
The command is mkdir, short for “make directory.” At its simplest, you just give it a name and it obliges.
mkdir my_new_project
Boom. Done. A new directory appears. You feel powerful. This is the peak of your day. Savor it.
But life is rarely that simple. You’ll quickly find yourself needing to create a whole path of directories, like projects/2024/quarter_3/experimental/please_dont_delete. If you just run mkdir on that whole string, the shell will promptly and rudely tell you it can’t do that.
mkdir projects/2024/quarter_3/experimental/please_dont_delete
# mkdir: cannot create directory ‘projects/2024/quarter_3/experimental/please_dont_delete’: No such file or directory
It’s not being difficult; it’s following orders. By default, mkdir is a bit literal. It looks at the path you gave it and tries to create the very last part (please_dont_delete). But to do that, it needs the parent directory (experimental) to already exist. Which it doesn’t. So it gives up. This is the most common mkdir face-palm moment.
The -p Flag: Forcing Sanity Upon the Filesystem
This is where the -p flag (which stands for “parents”) comes in like a superhero. It tells mkdir: “Look, I don’t care what it takes. Make this entire path happen. If any of the parent directories in the middle are missing, just create those too. Don’t ask questions.”
mkdir -p projects/2024/quarter_3/experimental/please_dont_delete
This command creates the entire tree in one fell swoop. It’s silent on success, which is its way of saying, “Job done. You’re welcome.” This flag is arguably the one you’ll use 95% of the time. It’s the difference between a useful tool and a pedantic one.
Why Wouldn’t You Always Use -p?
Good question. The default, non--p behavior exists as a safety net. It’s a way for the filesystem to yell, “Hey, are you sure?!” If you meant to create a directory inside an existing projects/ folder but you typo’d it as projecs/, the error stops you from creating a new, incorrectly named tree. Without -p, it fails fast and tells you something might be wrong with your assumptions about what already exists. With -p, it would blindly create projecs/2024/... and you might not notice your mistake for weeks.
Handling Spaces in Directory Names: The Great Trap
This is where everyone gets bitten. You want to create a directory called “My Important Files”. If you just type mkdir My Important Files, you’re not creating one directory; you’re creating three: one named My, one named Important, and one named Files. The shell splits arguments on spaces.
You have two sane options. First, use quotes:
mkdir "My Important Files"
Second, use escape characters:
mkdir My\ Important\ Files
Both tell the shell to treat the entire string as a single argument. Pick one and be consistent. I’m a quotes person, myself. It feels cleaner.
Setting Permissions At Creation Time
You can also set the permissions (mode) for the new directory right in the mkdir command using the -m (mode) flag. This is fantastic for when you need a directory to have specific permissions from the get-go, like a shared directory that needs group write permissions.
mkdir -m 775 shared_workspace
This creates shared_workspace with permissions rwxrwxr-x, meaning the owner and group can read, write, and enter the directory, while others can only read and enter. Doing this in one step is more efficient and atomic than running mkdir followed by chmod.
The -v Flag for the Anxious Among Us
If the silent success of mkdir -p makes you nervous—“Did it work? Did it do what I think it did?"—the -v (verbose) flag is your friend. It tells mkdir to narrate its entire existence.
mkdir -pv projects/2024/quarter_3/experimental/please_dont_delete
# mkdir: created directory ‘projects’
# mkdir: created directory ‘projects/2024’
# mkdir: created directory ‘projects/2024/quarter_3’
# mkdir: created directory ‘projects/2024/quarter_3/experimental’
# mkdir: created directory ‘projects/2024/quarter_3/experimental/please_dont_delete’
It’s a bit chatty, but incredibly useful for debugging complex scripts or just reassuring yourself that the command understood your intent. You can combine -p and -v like I did above, because the Unix philosophy is all about composing simple tools into powerful solutions. Now go forth and create directory structures with the confidence of someone who won’t accidentally pollute their home directory.