1

I need to create and navigate to a directory with one line of command. And it needs to be inside a function. I'm new to terminal and shell scripting and don't know much about it.

My process goes like this:

I write the name of the directory and it is stored to $dirname variable, and then type "create" and it is stored to another variable named $thecommand, to create the directory with the name I gave, and navigate to it.

I have a create() function. Inside the function I did mkdir ./$dirname, and then cd $dirname. Then I applied a condition: if what the user wrote in $thecommand variable (BTW both $dirname and $thecommand are read, so the user writes the value) is equal to "create".

The directory was created, but it didn't navigate to it. So I tried creating an alias p="$dirname", and applied the alias in the function, still, it created the directory, but didn't navigate!

I would appreciate if someone helped me with this.

Here is my code:

echo "Write Folder name"
read dirname
echo "Write -create- to create the folder"
read thecommand

p="$dirname"

function create() {
    mkdir ./"$p"
    cd "$p"
}

if [ "$thecommand" == "create" ]
then
    create
fi
  • A good place to start is tracing execution with `bash -x yourscript`. BTW, note that `cd` only applies within the shell running your script, **not** the shell that *started* your script. – Charles Duffy May 18 '19 at 12:39
  • ...so, where/how are you testing if the directory changed? If you want it to be changed *for the rest of your script* and it isn't, that's a bug. If you want it to be changed *after your script exits*, that's impossible if you keep your script in an interpreter separate from the interactive shell that invoked it (and we have lots of duplicates for questions asking that). – Charles Duffy May 18 '19 at 12:43
  • ...as another aside, the only POSIX-specified string comparison operator is `=`, not `==`. The latter is a common extension, but won't work on minimal shells like dash, so it's good practice to be in the habit of using the former. – Charles Duffy May 18 '19 at 12:44
  • Charles Duffy, when I execute the script on terminal, I want it to navigate to the created directory when i create it. And when I execute it, the folder is created, all good, but the path wasn't navigated there (in the sense that when i want to create another file direct from terminal, for example "touch test.txt", it's won't create on the new folder, but on the one I was from the beginning). I didn't mean to complicate it too much, I hope you understood me. Btw thanks for the comparison operator tip! – Beis Presheva May 18 '19 at 13:11
  • You *cannot* change your interactive shell's working directory from a script run in a subprocess, full-stop. (You can write a function *executed in the interactive shell itself* that does that, or you can source the script into the interactive shell so it runs there locally, but it has to be run *in* the interactive shell to change the interactive shell's working directory). – Charles Duffy May 18 '19 at 15:26

1 Answers1

0

There are a few things you can do.

First, just modifying the mkdir function in your .bashrc or .bash_aliases

function mkdir() {
  command mkdir -p $1  # This creates the folder
  command cd $1        # Then it immediately switches
  command pwd          # Remove this if you don't need confirmation. This just prints out current directory
}

If you don't want that to happen every time, you can just change the function name to create or whatever you prefer.

function create() {
  command mkdir -p $1     # Note: the `-p` flag just creates a folder, 
                          # like if you do `mkdir test/more` 
                          # you will get an error that it is not valid. 
                          # This does not change a regular `mkdir` command

  command cd $1
  command pwd
}

Or, you could just cd into the newly created folder

yaas
  • 144
  • 2
  • 7
  • Quote `"$1"` or this will all behave badly with names with spaces. – Charles Duffy May 18 '19 at 12:41
  • Also, note that `function funcname() {` is merging two different function declaration syntax forms -- the legacy ksh `function funcname {` and the POSIX `funcname() {` -- in a way that isn't compatible with *either* legacy ksh or POSIX. See also https://wiki.bash-hackers.org/scripting/obsolete – Charles Duffy May 18 '19 at 12:42
  • I'd also consider putting `|| return` on any command that should cause the function to bail out should it fail (if `mkdir -p` fails, you presumably don't want to go through with the `cd`). – Charles Duffy May 18 '19 at 12:42
  • If i make these changes in .bashrc or .bash_aliases, does that mean that only my computer can recognize this function? And if another computer tries to execute the script, it i won't work, right? Because this script needs to be executable in every computer – Beis Presheva May 18 '19 at 12:54