How to Combine mkdir and cd into a Single Command in Linux

 


Okay, if you spend any real amount of time in a Linux terminal, you've almost definitely run into this exact repetitive little pattern, you create a new folder with mkdir, and then immediately have to type out a whole separate cd command just to actually move into that folder you just made. Two separate commands, two separate keystrokes, every single time, just to do one logical action, "make a folder and go into it."

It's not a huge deal on its own, sure, but if you're doing this dozens of times a day like a lot of us are, it genuinely adds up to a surprising amount of wasted typing. So let's fix that properly, I'll walk you through everything from quick one-liner tricks all the way up to building yourself a permanent custom command that handles this in a single step from now on.

Quick One-Liner Methods

Let's start with the fastest fixes you can use right now, without needing to set anything up permanently.

Command Chaining With &&

The simplest fix here is just chaining your two commands together using &&, like this:

mkdir folder_name && cd folder_name

This runs both commands in sequence, first creating the folder, then immediately navigating into it, all in one line.

Now, you might be wondering why use && specifically instead of just separating the commands with a semicolon (;). Here's the important distinction, a semicolon runs both commands regardless of whether the first one actually succeeded or not. So if mkdir fails for some reason, maybe the folder already exists, or you don't have write permissions in that location, a semicolon would still blindly attempt the cd afterward anyway, which could land you somewhere unexpected. Using && instead ensures the second command, cd in this case, only runs if the first command genuinely completed successfully. This small distinction genuinely matters for avoiding weird, silent failures down the line.

Using Shell Expansion Shortcuts

If you wanna avoid retyping the folder name twice entirely, Bash and Zsh both support a handy shortcut using $_, which represents the last argument from your previous command. So instead of typing the folder name out twice, you can do this:

mkdir folder_name && cd $_

Here, $_ automatically pulls in folder_name from the mkdir command right before it, meaning you only ever type the actual folder name once.

There's also a genuinely handy keyboard shortcut worth knowing here too. In both Bash and Zsh, pressing Alt + . automatically inserts the last argument from your previous command directly into your current prompt. So after running mkdir folder_name, typing cd , then pressing Alt + ., automatically fills in folder_name for you without needing to type it out again or even remember the $_ syntax. Genuinely useful once it becomes muscle memory.

Creating a Permanent mkcd Shell Function

The one-liners above are great for occasional use, but if this is something you're doing constantly throughout your day, it's honestly worth setting up a permanent custom command that handles the whole thing automatically. Let's build exactly that.

Why a Simple Alias Won't Cut It Here

Your first instinct might be to just create a standard Bash alias for this, but here's the problem, a regular alias can't properly accept positional arguments the way we need it to for something like cd. Aliases are genuinely just simple text substitutions, they don't have the logic capability to take an argument you type afterward and reuse it in two different places within the same command. For that kind of behavior, you actually need a proper shell function instead, which can accept, store, and reuse arguments the way we're looking for here.

Building the Function Step by Step

Here's the function itself, which you'll wanna add directly into your .bashrc file (or .zshrc if you're running Zsh instead):

mkcd() {
  mkdir -p -- "$1" && cd -- "$1"
}

Let's break down exactly what's happening in each piece of this, since understanding it makes it way easier to customize further down the line if you want to.

The -p flag attached to mkdir tells it to automatically create any necessary parent directories along the way if they don't already exist. So if you run mkcd projects/newapp/src, and neither projects nor newapp currently exist yet, the -p flag handles creating that entire nested folder structure in one go, rather than throwing an error because intermediate folders were missing.

The double dashes (--) appearing before "$1" in both commands are there specifically to prevent any folder name you type from accidentally being interpreted as a command flag instead of an actual argument. This matters more than you'd think, since folder names starting with a hyphen (which, admittedly, is rare, but does happen) could otherwise confuse the command into thinking you're passing it an option rather than a literal directory name.

And finally, wrapping "$1" in quotes ensures the function handles folder names containing spaces or special characters safely. Without these quotes, a folder name like "My Project" would get split into two separate arguments instead of being treated as one single folder name, which would break the whole function entirely.

Applying the Changes

Once you've added this function into your .bashrc (or .zshrc), you need to actually load it into your current terminal session before it'll work. Just run:

source ~/.bashrc

Or if you're on Zsh:

source ~/.zshrc

From this point forward, anytime you wanna create a new folder and immediately move into it, you can just type mkcd folder_name, and it handles both steps automatically, in one single command.

Handling Edge Cases and Advanced Options

Once you've got the basic function working, there's a couple additional things worth considering if you wanna make it a little more robust.

Handling Missing or Multiple Arguments

Right now, if you run mkcd without actually providing a folder name, you'll just get a somewhat unhelpful error message from mkdir itself. If you'd rather have clearer feedback, you can extend the function slightly to check whether an argument was actually provided before attempting anything:

mkcd() {
  if [ -z "$1" ]; then
    echo "Usage: mkcd <directory_name>"
    return 1
  fi
  mkdir -p -- "$1" && cd -- "$1"
}

This adds a quick check at the start, and if no argument's been given, it prints a clear usage message instead of just letting mkdir fail silently with a less obvious error.

If you're someone who occasionally wants to create multiple nested folders and land inside the deepest one specifically, the base function already technically handles this fine, since something like mkcd project/src/components creates the full nested path and drops you directly into the final components folder, thanks to that -p flag we covered earlier.

Shell Compatibility Considerations

This exact function syntax works identically in both standard Bash and Zsh, since the core function syntax is shared between the two shells. If you happen to be running Fish shell instead though, the syntax structure's genuinely different, Fish uses its own distinct function definition format rather than the Bash-style curly brace syntax shown above. If you're a Fish user, you'd need to adapt this into Fish's specific function syntax instead, though the underlying logic, checking for an argument, creating the directory, then navigating into it, remains conceptually identical regardless of which shell you're actually running.

Honestly, a change this small feels almost too minor to bother writing about, and yet once mkcd becomes part of your regular terminal habits, going back to manually typing out mkdir followed by a separate cd command every single time just feels like unnecessary extra typing. It's a genuinely small productivity win, but these little automated shortcuts stack up meaningfully over time, especially if you're someone who lives in the terminal regularly.

If this one's useful to you, it's honestly worth taking a look through your other regularly repeated terminal habits too, chances are there's a handful of other small, repetitive command sequences in your daily workflow that could benefit from being turned into their own custom function or alias, just like we did here.

Post a Comment

0 Comments