🚀 Executive Summary
TL;DR: The common `mkdir -p` and `touch` sequence for creating nested directories and a file is inefficient and prone to errors. Solutions like the `touch-all` NPM package, a custom shell function, or the native `install -D` command streamline this process into a single, more reliable operation.
🎯 Key Takeaways
- The Unix philosophy of ‘do one thing and do it well’ explains why `mkdir` and `touch` are separate commands, leading to the need for a ‘double-command dance’ for nested file creation.
- The `touch-all` NPM package provides a modern, lightweight (2kb) TypeScript solution for creating nested directories and a file in a single command, ideal for Node.js environments.
- A custom shell function (e.g., `mkfile() { mkdir -p “$(dirname “$1″)” && touch “$1”; }`) offers a dependency-free, portable, and highly customizable method for this task on any Linux system.
SEO Summary: A brief look into replacing the tedious mkdir -p and touch dance with modern tools like touch-all. We explore why this shell pain point exists and three practical ways to solve it in your daily workflow.
Tired of the mkdir and touch Dance? Let’s Talk About touch-all
Last Tuesday, I was shadowing one of our newer engineers who was tasked with setting up a custom logging directory on prod-worker-02. I watched via screen share as they painstakingly typed out mkdir -p /opt/techresolve/logs/ingest/queue/ followed immediately by touch /opt/techresolve/logs/ingest/que/stream.log. They misspelled “queue” in the second command, creating a completely separate directory tree. We spent the next fifteen minutes chasing down a phantom file-not-found error. Frustrated, they asked, “Why can’t Linux just make the file and the folders at the same time?” I chuckled because I’ve felt that exact frustration since my early sysadmin days. It’s a shell rite of passage, but honestly, it is an incredibly annoying one.
Why Doesn’t touch Just Create Directories?
The root cause of this annoyance boils down to the foundational Unix philosophy: “Write programs that do one thing and do it well.” The mkdir command’s only job is to create directories. The touch command’s primary job is to update file timestamps, though it conveniently creates an empty file if one doesn’t exist. Unix tools are stubbornly literal and refuse to guess your intentions. While this strict separation makes operating systems incredibly predictable and stable, it ignores the reality of modern development workflows where scaffolding deep, nested directory structures is an hourly occurrence.
Three Ways to Fix the Nested-File Problem
You don’t have to suffer through the double-command dance forever. When a Reddit thread popped up recently about a 2kb TypeScript package called touch-all, it sparked a great debate on my team. Here are three distinct ways we bypass this limitation in the trenches.
1. The Quick Fix: The touch-all NPM Package
If you are already working in a JavaScript or Node.js environment, the touch-all tool is a brilliant, lightweight solution. It wraps the logic into a single, clean command that does exactly what you expect.
npm install -g touch-all
touch-all /opt/techresolve/new/deep/path/file.txt
It’s elegant and handles edge cases beautifully. However, as a Lead Cloud Architect, I get twitchy about installing global NPM packages on bare-metal database servers just to create files. It’s fantastic for your local Mac or a CI/CD pipeline, but I wouldn’t let it near prod-db-01.
2. The Permanent Fix: A Custom Shell Function
My personal favorite solution is to bake a function directly into your shell profile, like your .bashrc or .zshrc. This requires zero external dependencies and works on virtually any Linux box you SSH into.
mkfile() {
mkdir -p "$(dirname "$1")" && touch "$1"
}
Once you reload your profile, you simply type mkfile /any/deep/path/you/want/file.txt and let the shell do the heavy lifting. I practically force all my juniors to add this to their dotfiles on day one.
Pro Tip: If you use infrastructure automation tools like Ansible or Terraform, never rely on custom shell aliases. Always use the automation framework’s native file modules, like Ansible’s
filemodule withstate=touch, to ensure your deployments remain idempotent.
3. The ‘Nuclear’ Option: The Native GNU Install Command
What if you are troubleshooting a restricted server, you cannot install NPM packages, and you aren’t allowed to edit the bash profile? You use a slightly hacky, obscure built-in command. The install command is traditionally used by Makefiles to copy binaries around, but it has a magic flag: -D.
install -D /dev/null /path/to/your/deep/nested/file.txt
This tells the OS to copy the empty void of /dev/null into your target destination, automatically creating all missing parent directories along the way. It is a bit of a dark art, and it might confuse the next engineer who reads your command history, but it works flawlessly without a single line of third-party code.
Comparing the Options
| Solution | Pros | Cons |
touch-all (NPM) |
Clean syntax, cross-platform (Windows/Mac/Linux). | Requires Node.js overhead, overkill for a raw server. |
| Shell Function | Zero dependencies, highly customizable and fast. | Needs to be set up on every individual machine you use. |
install -D |
Native to GNU/Linux, works out of the box everywhere. | Obscure syntax, undeniably a hacky workaround. |
At the end of the day, choose the tool that fits your context. If you are writing TypeScript microservices all day, grab touch-all and enjoy the simplicity. If you are a grizzled DevOps engineer jumping between fifty different servers a week, stick a function in your profile and get back to building.
🤖 Frequently Asked Questions
âť“ How can I create a file and all its parent directories simultaneously in Linux?
You can use the `touch-all` NPM package (`npm install -g touch-all; touch-all /path/to/file.txt`), a custom shell function like `mkfile() { mkdir -p “$(dirname “$1″)” && touch “$1”; }`, or the native `install -D /dev/null /path/to/file.txt` command.
âť“ How does `touch-all` compare to alternative methods for creating nested files?
`touch-all` offers clean syntax and cross-platform compatibility but requires Node.js overhead. A custom shell function is dependency-free, fast, and customizable but needs per-machine setup. The `install -D` command is native to GNU/Linux and works everywhere but uses obscure syntax and is considered a hacky workaround.
âť“ What is a common implementation pitfall when automating nested file creation with infrastructure tools?
When using infrastructure automation tools like Ansible or Terraform, never rely on custom shell aliases or functions. Instead, always use the automation framework’s native file modules (e.g., Ansible’s `file` module with `state=touch`) to ensure deployments remain idempotent and avoid dependencies on custom shell configurations.
Leave a Reply