I find this function online. It's does creating a directory and changing to directory.

But I want to know every part of it.

function mkdircd () { mkdir -p "$@" && eval cd "\"\$$#\""; } 

2 Answers 2


You can pass in a list of names. It will create directories for each of them, then cd into the last one.

This does not need eval. I would write it like this:

mkdircd () { mkdir -p "$@" && cd "${!#}"; }

${!#} uses indirect expansion: $# is the number of parameters, so ${!#} is the value of the last parameter

  • Still so much to learn. Thank you for link.
    – Raja G
    May 10, 2016 at 16:14
  • Of course if you've used brace expansion it still won't work as expected, will it? E.g. mkdircd dir{1..3} will put you in the first of the three brace expanded dirs.
    – Wildcard
    May 10, 2016 at 16:31
  • 1
    Yes, no problem: brace expansion occurs before the function is called, so you are passing 3 distinct arguments in that example. May 10, 2016 at 16:32
  • Ahh, good point. Whereas cd dir{1..3} will put you in dir1.
    – Wildcard
    May 10, 2016 at 16:33
  • 1
    This doesn't need eval in bash, but using eval makes it work in other shells. May 10, 2016 at 22:57

mkdir -p "$@" create all the directories which name are passed as arguments ($@).

The -p option allow to create recursively the directories if they are in directories which don't exist.

eval cd "\"\$$#\"" just go to the last directory: $# give you the number of argument passed, thus \$$# will give you the last argument (i.e: the last directory name you passed as an argument). For example, if there are three arguments, $# is 3, so eval runs the command cd "$3".

The command should actually have been eval cd "\"\${$#}\"". The braces are necessary in many shells when there are 10 arguments are more, because many shells treat something like "$10" as the value of parameter 1 followed by the character 0 and not as the value of parameter 10.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .