3

I'm trying to write a very simple mkcd command:

#!/bin/bash
mkdir $1
cd $1

The directory is created but the change directory part doesn't seem to run.

Update based on comment:

mkcd () {
  mkdir "$1"
  cd "$1"
}

I'm trying to run it first as a local file:

./mkcd

My end location is /opt/bin, neither location seems to work.

techraf
  • 5,831
  • 10
  • 33
  • 51
Philip Kirkbride
  • 9,816
  • 25
  • 95
  • 167
  • 4
    Note that the call to `cd` *does* run - but its effect is lost as soon as the subshell running the script dies. – D_Bye Dec 08 '16 at 13:38
  • My extended version of [PSkocik's answer](https://unix.stackexchange.com/a/328964/270469): `mkcd() { if [ ! -d "$@" ];then mkdir -p "$@" ;fi; cd "$@"; }` (Posted as comment because answering is disabled here.). – neverMind9 Jun 20 '19 at 20:31

1 Answers1

8

It needs to be a function:

mkcd() { mkdir -p "$1" && cd "$1"; } 

A script will get run inside its own separate process. Changing directories there will have no effect on the parent shell (neither will changing directories inside a subshell as in (cd /tmp)).

Petr Skocik
  • 28,176
  • 14
  • 81
  • 141
  • With that it doesn't seem to make the folder. I will double check that I did it exact. – Philip Kirkbride Dec 08 '16 at 13:39
  • It's a function so you'd place it inside your `.bashrc` or an insourcable text file placed in a `$PATH` directory. You'd then include the textfile with `. the_textfile.sh` (assuming it's named `the_textfile.sh` -- `the_textfile.sh` need not and should not be marked executable with `chmod`). Since this file is insourced with `.` (or `source`) (implicitly done for bash startup files such as `.bashrc`) and not executed, a shebang line makes no sense there (it will be interpreted as just a comment). – Petr Skocik Dec 08 '16 at 13:40
  • I have always put these types in /opt/bin with chmod +x (should that work?). The function is found when I run mkcd but nothing happens. It must be another issue with my system because I also tried copying from here. http://unix.stackexchange.com/questions/9123/is-there-a-one-liner-that-allows-me-to-create-a-directory-and-move-into-it-at-th – Philip Kirkbride Dec 08 '16 at 13:47
  • @PhilipKirkbride Make it a `mkcd.sh`, have it in your `/opt/bin`, don't `chmod +x` it, and in your `.bashrc` add `. mkcd.sh`. Or just put `mkcd(){ mkdir -p "$1" && cd "$1"; }` inside your `.bashrc` and don't bother with the insourcable. – Petr Skocik Dec 08 '16 at 13:50
  • when I try that I get mkcd not found. I can use mkcd.sh globally but because I did chmod -x, permission is denied. Will try .bashrc method. – Philip Kirkbride Dec 08 '16 at 13:53
  • 2
    I think problem was I didn't close the terminal to refresh my .bashrc – Philip Kirkbride Dec 08 '16 at 13:55
  • 1
    My version: `mkcd() { if [ ! -e "$@" ];then mkdir -p "$@" && cd "$@";fi; } `. – neverMind9 Jun 20 '19 at 20:20
  • 1
    @neverMind9 I kind of assume it was for interactive use and therefore time wasn't of the essence. `[ -d "$1" ] || mkdir -p "$1"` is good for saving time on process start overheads in scripts, though. (I think `-d` is better than `-e` because then you'll run `mkdir` iff the arg isn't a directory and `mkdir` will then generate an error message for you). – Petr Skocik Jun 20 '19 at 20:25
  • 1
    @PSkocik Sorry for the mistake in the last one. I updated it (and moved the “cd” part outside of the “if” request): `mkcd() { if [ ! -d "$@" ];then mkdir -p "$@" ;fi; cd "$@"; } `. – neverMind9 Jun 20 '19 at 20:28