Combined `mkdir` and `cd`?
Solution 1
Function?
mkcdir ()
{
mkdir -p -- "$1" &&
cd -P -- "$1"
}
Put the above code in the ~/.bashrc
, ~/.zshrc
or another file sourced by your shell. Then source it by running e.g. source ~/.bashrc
to apply changes.
After that simply run mkcdir foo
or mkcdir "nested/path/in quotes"
.
Notes:
"$1"
is the first argument of themkcdir
command. Quotes around it protects the argument if it has spaces or other special characters.--
makes sure the passed name for the new directory is not interpreted as an option tomkdir
orcd
, giving the opportunity to create a directory that starts with-
or--
.-p
used onmkdir
makes it create extra directories if they do not exist yet, and-P
used makescd
resolve symbolic links.- Instead of
source
-ing the rc, you may also restart the terminal emulator/shell.
Solution 2
I think creating a function is the most appropriate way to do this, but just for listing all alternative ways, you could write:
mkdir foo && cd "$_"
$_
is a special parameter that holds the last argument of the previous command. The quote around $_
make sure it works even if the folder name contains spaces.
Why use double quotes?
In some shells, such as zsh
, the double quotes surrounding the $_
are not necessary even when the directory name contains spaces. They are required for this command to work in bash
, however.
For example, running this command in bash 3.2.57 on macOS 10.13.6:
mkdir "my directory" && cd $_
results in this output:
bash: cd: my: No such file or directory
However, if we surround $_
with double quotes, the command returns successfully.
bash-3.2$ mkdir "my directory" && cd "$_"
bash-3.2$ echo $?
0
bash-3.2$
Solution 3
Bash (using word designators):
/tmp/bug$ mkdir "some dir"
/tmp/bug$ cd !$
cd "some dir"
/tmp/bug/some dir$
!$
expands to the last argument of the previous line in the history. If you have parameters in between, then you can use !:1
for the first argument, !:2
forthe second argument, etc.
From bash(1):
Event Designators
An event designator is a reference to a command line entry in the history list. Unless the reference is absolute, events are relative to the current position in the history list.
!
Start a history substitution, except when followed by a blank, newline, carriage return,=
or(
(when the extglob shell option is enabled using the shopt builtin).[..]
Word Designators
Word designators are used to select desired words from the event. A
:
separates the event specification from the word designator. [..][..]
n The n-th word.
^
The first argument. That is, word 1.
$
The last word. This is usually the last argument, but will expand to the zeroth word if there is only one word in the line.
Solution 4
These other lads are just making life complicated, here it is:
eval {mkdir,cd}\ FOLDER\;
Jasper
Updated on September 18, 2022Comments
-
Jasper almost 2 years
is there any way (what is the easiest way in bash) to combine the following:
mkdir foo cd foo
The manpage for
mkdir
does not describe anything like that, maybe there is a fancy version ofmkdir
? I know thatcd
has to be shell builtin, so the same would be true for the fancymkdir
...Aliasing?
-
Admin about 10 yearsYou can't alias two commands together directly.
-
-
Jasper about 10 yearsand put this in .bashrc?
-
Ouki about 10 yearsexactly ;) ... no big deal
-
Ouki about 10 years@glenn jackman: thanks for the
"$1"
-
Stéphane Chazelas about 10 years
!$
is shorter and easier to type on many keyboards. See also<Alt-.>
or<Alt-_>
-
Lekensteyn about 10 years@StephaneChazelas Nice one, I'll update the answer to use
!$
instead. -
Lekensteyn about 10 years@bernard you can move forward and backward in the parameter list. See the manual page of bash.
-
Admin about 10 yearsI really wanted to make a directory called
'FOLDER && rm ../something'
. Buteval
won't let me :*( Tragically, may have to choose complicated in the battle of complicated vs evil. -
Sean D about 10 years@BroSlow, well then you'll have to find another OS, since having a slash in a filename has never been allowed! as for the other characters they work just fine if escaped.
-
Admin about 10 years@SeanD You're missing my point. Using
eval
with user input is generally a bad idea andeval
will processFOLDER && rm ../something
in place ofFOLDER
without complaint. Or for another variant, how about"FOLDER && rm -r $HOME"
-
Miles Rout over 8 years@BroSlow This isn't using
eval
with user input, so it's fine. Don't cargo cult. -
Zaz over 7 yearsWhat's the purpose of
--
? -
antak over 7 yearsSame line version of
$!
, in this case, is!#:1
. i.e."$_"
can be replaced with!#:1
. -
immeëmosol over 7 years@Zaz
--
is used to make sure that the following parameters are not parsed as a options to modify the behaviour of the command. In this case it makes sure the passed name for the new directory is not interpreted as an option to mkdir or cd, giving the option to create a directory that starts with - or -- . -
immeëmosol over 7 yearsIn case someone's wondering, the
-P
used makes cd resolve symbol links. The-p
used on mkdir makes it create extra directories if they do not exists yet. -
MarSoft over 7 yearsStrange, but this answer doesn't work for me. It works when I start
bash --norc
, but when config is active thenecho $_
echoes$_
, whileecho ${_}
works. I couldn't find the reason. Probably${_}
is more safe variation and should be used in the answer? -
MarSoft over 7 yearsAlso, without
--norc
, this commandecho abc; echo def; echo $_
echoesabc def $_
(each on new line). When using--norc
, the same command yieldsabc def def
(each on new line). -
Zajn over 7 years@MarSoft Weird! I wonder if it's a difference in the version of
bash
? It works for me underbash 4.3.46
whether if I supply--norc
or not. I would be curious to see what yourbashrc
looks like if it works when starting the shell without config, even though I don't think you can modify special parameters like_
. -
MarSoft over 7 years@Zajn, I found that the culprit is a
git-prompt
script. Yet to determine how does it achieve such behaviour :) Probably anyPROMPT_COMMAND
will influence the$_
? -
Zajn over 7 years@nyxee
$_
's value will befoo
in this example. If I had instead typedmkdir workspace
, the value of$_
would have beenworkspace
, andcd "$_"
would change our current directory to the newly createdworkspace
. Does that make sense? -
user2067125 almost 7 yearsDoes not work inside of shell & works perfectly at command prompt.
-
Suhaib almost 7 yearswhy did you add the double quotation ? I just tried and It works without it. Also, it makes it look really ugly and might discourage some people
-
Zajn almost 7 years@Suhaib Without the double quotes, this command will not work correctly using
bash
. I've tried it inzsh
and confirmed that it works without the double quotes, but since the question was tagged withbash
, I answered accordingly. -
Zajn almost 7 years@Suhaib As explained in the answer, the double quotes ensure that the command works if the directory name contains spaces. Try running
mkdir "test folder" && cd $_
inbash
and see the result. I should have specified in my last comment that this pertains to directories with spaces in their names. -
Tofeeq over 6 yearsI normally use $ mkdir gulp && cd gulp in my arch linux
-
Asotos over 6 yearsIn case someone is wondering: You need to put the function in .bashrc and then add a line
export <name_of_my_function>. Then
source ~/.bashrc` or restart terminal, and the function will be available as a command. I really think the comments should be integrated into the answer, but I don't want to intrude to someone else's answer. -
Zajn almost 6 years@SHiON Adding double-quotes is necessary in
bash
when creating a directory that contains spaces. Since the question is tagged forbash
, I answered accordingly. -
nroose over 5 yearsI am calling it
mc
! -
harperville over 5 yearsI find it humorous that the best answer here is one that ends with an error:
bash: cd: my: No such file or directory
. I mean, it shows that thecd
is being invoked andmy
is the argument butpwd && mkdir thisdir && cd $_ && pwd
demonstrates the point without an error. All the same, TIL about the$_
command. Thanks! -
Zajn over 5 years@harperville The reason for the error at the end of the answer is to demonstrate the need for quotes surrounding
$_
in certain shells, namelybash
. Perhaps I should re-word that section to more clearly state that without the"$_"
, that is the error you will see. -
Mark Han over 4 yearsDo we need an
|| exit
following the cd? e.g.mkdir -p -- "$1" && cd -P -- "$1" || exit
-
Ouki over 4 years"exit" would mean "logout" : I am sure you do not want that ^^
-
Positive Navid almost 4 yearsOther than typing "mkdir", "cd", white space, and theFolderName, this answer requires typing only 2 more characters. That's how I evaluate the best answer
-
qwertz about 3 yearswhen using oh-my-zsh there is a function
take
defined, so you can use something liketake somenewdir
. The function looks like this:take () { mkdir -p $@ && cd ${@:$#} }