115

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 of mkdir? I know that cd has to be shell builtin, so the same would be true for the fancy mkdir...

Aliasing?

marked as duplicate by Stéphane Chazelas, Mikel, slm, Bernhard, jasonwryan Apr 18 '14 at 19:22

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • You can't alias two commands together directly. – goldilocks Apr 18 '14 at 14:05
  • 1
    Yes, seems to be a duplicate. Anything to do for me about that? – Jasper Apr 18 '14 at 16:21
  • 1
    Nope, just wait for it to be closed. Do not delete it, as being a different wording, it may still be useful for people searching the same based on terms in your question. – Stéphane Chazelas Apr 18 '14 at 16:52
87

Function?

mkcdir ()
{
    mkdir -p -- "$1" &&
      cd -P -- "$1"
}
  • 7
    quotes around "$1" will protect the argument if it has spaces. – glenn jackman Apr 18 '14 at 13:33
  • 8
    and put this in .bashrc? – Jasper Apr 18 '14 at 14:05
  • 4
    What's the purpose of --? – Zaz Nov 12 '16 at 21:25
  • 11
    @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 Jan 4 '17 at 11:12
  • 14
    In 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. – immeëmosol Jan 4 '17 at 11:14
220

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.

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
  • 7
    Neat, learned something new again! – Lekensteyn Apr 19 '14 at 13:31
  • 14
    I think this should be the accepted answer. :) – Milkncookiez Sep 8 '16 at 11:52
  • 4
    Definitely the answer I was looking for, basically wanted a same-line version of '$!'. – Jez W Sep 14 '16 at 9:08
  • 1
    Same line version of $!, in this case, is !#:1. i.e. "$_" can be replaced with !#:1. – antak Dec 7 '16 at 5:33
  • 2
    @nyxee $_'s value will be foo in this example. If I had instead typed mkdir workspace, the value of $_ would have been workspace, and cd "$_" would change our current directory to the newly created workspace. Does that make sense? – Zajn Feb 23 '17 at 15:56
17

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.

  • I think that "!:1" loses vs "$firstfewcharactersofnewdir+TAB" in most cases... – Jasper Apr 18 '14 at 14:19
  • @Jasper I seldomly use !:1, but it is an option if you have a path with a non-unique prefix. – Lekensteyn Apr 18 '14 at 14:34
  • 4
    !$ is shorter and easier to type on many keyboards. See also <Alt-.> or <Alt-_> – Stéphane Chazelas Apr 18 '14 at 14:51
  • 1
    @StephaneChazelas What is the difference between Alt+. and Alt+_? – Bernhard Apr 18 '14 at 19:03
  • 1
    @bernard you can move forward and backward in the parameter list. See the manual page of bash. – Lekensteyn Apr 18 '14 at 19:58
8

These other lads are just making life complicated, here it is:

eval {mkdir,cd}\ FOLDER\;
  • 2
    I really wanted to make a directory called 'FOLDER && rm ../something'. But eval won't let me :*( Tragically, may have to choose complicated in the battle of complicated vs evil. – BroSlow Apr 19 '14 at 2:14
  • 1
    @SeanD You're missing my point. Using eval with user input is generally a bad idea and eval will process FOLDER && rm ../something in place of FOLDER without complaint. Or for another variant, how about "FOLDER && rm -r $HOME" – BroSlow Apr 19 '14 at 17:28
  • 1
    @BroSlow, using microwaves is generally a bad idea too, since you might put in tinfoil. – Sean D Apr 20 '14 at 9:30
  • 1
    @SeanD Yes, but a microwave does what you would expect, eval doesn't. Simply put eval is evil and is almost never the right command to use, especially for something as simple as this. – BroSlow Apr 20 '14 at 17:29
  • 1
    @MilesRout If you only ever use it for a directory called FOLDER, sure, this is fine. That's not the point, if you use it with variable input (which you almost certainly are going to), the results for weird directory names can at best cause unexpected results, at worst pose a security risk. – BroSlow Feb 1 '16 at 1:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.