DEV Community

Carlo Lobrano
Carlo Lobrano

Posted on

Let mkdir create parents directories

I noticed that it is more than a year since the last post, so I thought that a small new content would have been easier to write.
This in particular refers to an extension I wrote some time ago for the mkdir system call to make it a bit more proactive πŸ˜„.

90% of the times, I use mkdir to create a new folder in the current directory, so the few times I want to create a new folder in a deeper path I always forget to add the --parent flag.

me/blog $ mkdir foo/bin/bar
mkdir: cannot create directory β€˜foo/bin/bar’: No such file or directory
Enter fullscreen mode Exit fullscreen mode

as the Man-pages would tell you, since the parent directory foo/bin does not exist, mkdir fails to create bar, but what if mkdir were so kind to tell me just that, and suggests to add the flag on my behalf? πŸ˜„

This is actually somehow easy.

First of all, you need a way to define new functions in your shell. I use zsh, but in bash would be the same: write a function definition in a file and source it in .bashrc or .zshrc.

This comes from my .zshrc

#
# Functions and aliases
#
source ~/.dot/.config/cconf/zsh/functions.zsh
Enter fullscreen mode Exit fullscreen mode

What to do for mkdir?

  1. override it with a custom function ➑️ function mkdir() {}
  2. find the parent directory mkdir expects to exist already ➑️ echo $1 | grep -E -q '[\S+/]+'
  3. if it doesn't exist, ask if it must be created or not ➑️ echo "Press ENTER to run mkdir with --parents."

Ok, point 2 probably requires some explaination, so let's back to the example above

me/blog $ mkdir foo/bin/bar
Enter fullscreen mode Exit fullscreen mode

bar is the folder to be created, while foo/bin/ is the parent.
The grep expression above looks for any sequence of substrings ending with slash /: foo/, foo/bar/, etc., but not bar, or foo, which would be a directory in the current folder.

So putting all these pieces together:

function mkdir() {
    # extend mkdir with custom features
    # propose adding "--parents" flag.
    echo $1 | grep -E -q '[\S+/]+'
    if [[ $? == 0 && ! -d $1 ]]; then
        # one of the directories in $1 path do not exist
        # suggest adding "--parents" flag.
        echo "# Some parents in $1 do not exist. Press ENTER to run mkdir with --parents."
        read
        command mkdir --parents $@
        echo "# done"
    else
        command mkdir $@
    fi
}
Enter fullscreen mode Exit fullscreen mode

Let's try again

me/blog $ mkdir foo/bin/bar                                                                                    
# Some parents in foo/bin/bar do not exist. Press ENTER to run mkdir with --parents.

# done

me/blog $ tree | grep -e foo -e bar -e bin
β”œβ”€β”€ foo
β”‚   └── bin
β”‚       └── bar
Enter fullscreen mode Exit fullscreen mode

Of course in a similar manner you can override rm as well (see here).

Top comments (0)