92

I used 'change directory' in my shell script (bash)

#!/bin/bash
alias mycd='cd some_place'
mycd
pwd

pwd prints some_place correctly, but after the script finished my current working directory doesn't change.

Is it possible to change my path by script?

2

7 Answers 7

98

You need to source the file as:

. myfile.sh

or

source myfile.sh

Without sourcing the changes will happen in the sub-shell and not in the parent shell which is invoking the script. But when you source a file the lines in the file are executed as if they were typed at the command line.

0
22

While sourcing the script you want to run is one solution, you should be aware that this script then can directly modify the environment of your current shell. Also it is not possible to pass arguments anymore.

Another way to do, is to implement your script as a function in bash.

function cdbm() {
    cd whereever_you_want_to_go
     echo arguments to the functions were $1, $2, ...
}

This technique is used by autojump: http://github.com/joelthelion/autojump/wiki to provide you with learning shell directory bookmarks.

1
  • I was able to pass arguments to a sourced script as in source my_script.sh myarg myarg made it into the script as $1
    – dolphus333
    Commented Dec 21, 2019 at 14:31
19

The script is run in a separate subshell. That subshell changes directory, not the shell you run it in. A possible solution is to source the script instead of running it:

# Bash
source yourscript.sh
# or POSIX sh
. yourscript.sh
0
5

It can be achieved by sourcing. Sourcing is basically execute the script in the same shell whereas normal execution(sh test.sh or ./test.sh) will create sub shell and execute script there.

test.sh

cd development/
ls
# Do whatever you want.

Execute test.sh by

source test.sh

. is shortest notation for source. So you can also do by

. test.sh

This will execute the script and change the directory of current shell to development/.

3

Another practical solution is to end your script by opening another shell session. For instance:

#!/bin/bash
cd some_place
bash

This is useful, in my case, for scripts located in my ~/bin for instance, called from any other place. It is just a bit painful to type source ~/bin/mygoodoldscript instead of mygoo<TAB><ENTER>.

The downside is that the additional shell takes up a few more resources (not much).

1
  • 1
    To use slightly fewer extra resources, you can use exec bash, which will replace the current process with a new instance of bash. Note that this will still result in a nested subshell, but with one fewer process (nested two levels deep rather than three). Commented Mar 18 at 23:02
2

whenever you run a script on your login shell, a new subprocess is spawned and the script execution is done in a subshell.Once the script completes, the subshell exits and you are returned to the login shell.Hence whenever you do a cd through a script,the directory is changed to the path specified by cd, but by the time script finishes you come back to your login shell to the working directory from where you started the script.

The way to overcome this is use,

source yourscript.sh

what source does is it executes the script as TCL script, i.e it has the same effect as when you typed each line on the command line of your login shell and it executed from there. So this way when the script finishes after cd , it stays in that directory.

0
0

Though there are answers. I think the intention of question is to use script to navigate to specific path.

Here is a simple practical solution works here without cancel out existing terminal environment flag.

  1. provide a bash/tch/sh script to work for path generation
/* .goto.sh */
#!/usr/bin/env bash
echo '~/workspace'
  1. add alias to the script output
alias goto 'cd `.goto.sh`'

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