Combined `mkdir` and `cd`? [duplicate]
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?
4 Answers 4
I think creating a function is the most appropriate way to do this, but just for listing all alternative ways, you could write:
$_ 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:
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$
@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?
why 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
@SHiON Adding double-quotes is necessary in bash when creating a directory that contains spaces. Since the question is tagged for bash , I answered accordingly.
@harperville The reason for the error at the end of the answer is to demonstrate the need for quotes surrounding $_ in certain shells, namely bash . Perhaps I should re-word that section to more clearly state that without the «$_» , that is the error you will see.
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» .
- «$1» is the first argument of the mkcdir 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 to mkdir or cd , giving the opportunity to create a directory that starts with — or — .
- -p used on mkdir makes it create extra directories if they do not exist yet, and -P used makes cd resolve symbolic links.
- Instead of source -ing the rc, you may also restart the terminal emulator/shell.
@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 — .
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.
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.
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.
How can I have mkdir cd into the newly-created directory? [duplicate]
How can I have mkdir cd into the newly-created directory? By that I mean if I mkdir something , than the command cd something is executed immediately after. Example:
$ pwd /home/me $ mkdir something $ pwd /home/me/something
4 Answers 4
Using last argument of command
You don’t have to retype the name of the directory created. Use $_ variable:
_ At shell startup, set to the absolute pathname used to invoke the shell or shell script being executed as passed in the environment or argument list. Sub‐ sequently, expands to the last argument to the pre‐ vious command, after expansion.
bash-4.3$ mkdir mydir bash-4.3$ cd $_
Using the » compound command
If we wanted use just one line, combine the commands into compound command < (note that leading space before < and semicolons for each command are required):
bash-4.3$ pwd /home/xieerqi bash-4.3$ < mkdir mydir;cd $_;>bash-4.3$ pwd /home/xieerqi/mydir
It’s important to note that this compound command structure is chosen for a reason, because all commands within the list are executed in current shell environment.
And if we want to avoid typing everything over and over, we can make an alias out of it.
Here I used «$d» variable for both , but I could have just as equally used «$_» :
(1) You should probably mention the fact that the ; between the last command and the > is required. This is a frequent source of confusion for people who are accustomed to ( cmd1 ; cmd2 ) grouping, where a ; is not required after the last command. (2) At the risk of splitting hairs, if you have a ; before the > , you don’t need a space. Also, of course, spaces before semicolons are not required, either. … (Cont’d)
(Cont’d) … (3) That’s a really clever trick, ending an alias with
(Cont’d) … (4) Using unnecessary external programs in aliases is inelegant. Here, the use of xargs is harmful. (4a) It strips leading and trailing whitespace from the argument. (4b) It turns interior whitespace into a single space (even if it is multiple spaces, or a tab). (4c) It strips out matching pairs of quotes, and goes crazy if you give it non-matching quotes. Why not just do ‘ < IFS= read -r arg && cmd1 «$arg» && cmd2 «$arg» ; >
@G-Man Very valid comments 1 and 4. I wasn’t aware that xargs has these issues. I’ve edited my answer. As for comment 5, we could use cd «$_» instead of using «$d» everywhere. Just a small point to link it with previous section of the answer, not really important.
I suggest creating a function:
it does what you want, you can add it to your .bashrc so it will be available in all your shells.
$ mydir ~/my-new-directory $ pwd ~/my-new-directory
Note: you can change mydir with mkdir to override it, however I suggest a custom name which does not exist in system like mydir or cmkdir ; You can check to see if a command exists using type command .
@choroba my mistake +1, I wrote it with quoting in my system that was the reason it was working okay, updated the answer 😉 thanks.
I usually follow mkdir something by cd Alt + . which completes the command with the last argument of the previous command, i.e. the directory name.
I have to use Esc instead of Alt . For some reason that works instead for me in both xterm and Terminator .
Function
You can make a small function, which you can store in the file ~/.bashrc . Edit the file to add the following lines,
in order to make the change work in the current terminal [window]. The new function will be there, when you open new terminals.
Using && between the commands makes the cd command run only if the mkdir command was successful.
Example: I can use the function md like this to create a test directory testdir in the current directory (in this case my home directory as seen from the prompt),
sudodus@xenial32 ~ $ md testdir sudodus@xenial32 ~/testdir $
Bash shellscript did not work as I expected
I will also describe my difficulties using a small bash shellscript for this purpose, because other people might try it and get confused.
You can store a shellscript in the directory ~/bin . After creating ~/bin and rebooting, it will be in PATH.
Use a name that is not used by any standard command (for example mdscript ),
Make the script executable
This does not work as intended with
because the current directory is only changed in the sub-process of the shell-script, but not in the terminal [window] after finishing the shellscript.
It works when ‘sourced’, run with the command line
but this is not convenient, not a good answer to the original question.
You can see how it works, if you add a pwd command into the shellscript
#!/bin/bash mkdir "$1" && cd "$1" pwd
and run the script mdscript
sudodus@xenial32 ~ $ mdscript testdir /home/sudodus/testdir sudodus@xenial32 ~ $