Skip to content

Instantly share code, notes, and snippets.

@kallmanation
Last active March 10, 2024 21:30
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kallmanation/2027bb23242e59cb90141c803ffe2703 to your computer and use it in GitHub Desktop.
Save kallmanation/2027bb23242e59cb90141c803ffe2703 to your computer and use it in GitHub Desktop.
mcd - mkdir && cd

mcd

Make and Change Directory

mkdir && cd

It's an often used pattern when setting up to first make a directory with mkdir and then immediately moving into the new directory with cd.

mkdir my_dir
cd my_dir

It's somewhat useful to combine these commands into one, mcd.

The code

mcd() { mkdir "$@" 2> >(sed s/mkdir/mcd/ 1>&2) && cd "$_"; }

Simply place the above in .bashrc or similar, or make a copy of mcd.sh for a portable executable.

Explanation

  • "$_" refers to the last argument of the previously executed command.
  • && executes the subsequent command iff the preceding command succeeds.
  • "$@" refers to all the arguments given to this command.
  • 2> >(sed s/mkdir/mcd/ 1>&2) redirects stderr into sed to replace mkdir with mcd and then redirects back onto stderr. This gives slightly more coherent error messages, but is not strictly necessary for the functionality.

Putting it together: we call mkdir with all the same arguments as passed to us; if we successfully create the directory, we call cd with the last parameter (aka the directory we just made).

Using "$@" instead of "$1" or similar has some benefits: mcd will respect any parameters passed, such as -p; it will also maintain the mkdir capability of creating multiple directories at once, cding into the last created one.

Examples

Starting from an empty pre-existing directory ~/mcd/

~/mcd $ mcd
usage: mcd [-pv] [-m mode] directory ...
~/mcd $ mcd A/B
mcd: A: No such file or directory
~/mcd $ mcd -p A/B
~/mcd/A/B $ cd -
~/mcd $ mcd A/B/C
~/mcd/A/B/C $ cd -
~/mcd $ mcd A
mcd: A: File exists
~/mcd $ mcd -p A
~/mcd/A $ mcd X Y Z
~/mcd/Z $ cd -
~/mcd/A $ ls
B X Y Z
mcd() { mkdir "$@" 2> >(sed s/mkdir/mcd/ 1>&2) && cd "$_"; }
@RMGiroux
Copy link

Suggestion: please add the -p option to mkdir:
mcd() { mkdir -p "$@" 2> >(sed s/mkdir/mcd/ 1>&2) && cd "$_"; }

That way, mcd foo/bar/baz will work even if foo or foo/bar aren't present yet.

@kallmanation
Copy link
Author

He @RMGiroux, thanks for the comment!

As written this will respect the -p flag when given. For example, mcd -p foo/bar/baz will create all the directories even if foo or foo/bar aren't present yet.

@RMGiroux
Copy link

So it will... I prefer the lazy option, but I can understand the choice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment