The simplest way is to use a shell function:
mkdir -p -- "$1" && cd -- "$1"
Place it in your
.bashrc file to make it be available to you just like another shell command.
The reason why it doesn't work as an external script is
cd changes the current directory of the running script but doesn't affect the calling one. This is by design! Each process has its own working directory which is inherited by its children, but the opposite is not possible.
Unless part of a pipeline, run in the background or explicitly in a subshell, a shell function doesn't run in a separate process but in the same one, just like if the command has been sourced. The current directory shell can then be changed by a function.
&& used here to separate both commands used means, if the first command succeeds (
mkdir), run the second one (
cd). Consequently, if
mkdir fails to create the requested directory, there is no point trying to go into it. An error message is printed by
mkdir and that's it.
-p option used with
mkdir is there to tell this utility to create any missing directory that is part of the full path of the directory name passed as argument. One side effect is that if you ask to create an already existing directory, the
mkcd function won't fail and you'll end up in that directory. That might be considered an issue or a feature. In the former case, the function can be modified for example that way which simply warns the user:
if [ -d "$1" ]; then
printf "mkcd: warning, \"%s\" already exists\n" "$1"
mkdir -p "$1"
fi && cd "$1"
-p option, the behavior of the initial function would have been very different.
If the directory containing the directory to create doesn't already exists,
mkdir fails an so does the function.
If the directory to be create already exists,
mkdir fails too and
cd isn't called.
Finally, note that setting/exporting
PWD is pointless, as the shell already does it internally.
Edit: I added the
-- option to both commands for the function to allow a directory name starting with a dash.