I've written a bash script which should cd me to a directory.

My problem is that only the directory in the subshell changes.

I've read of many similar problems to this, but I want to know if there is a solution besides using an alias, a function or sourcing the script.

If you don't understand what I mean, here's an example:

user@linux ~: cat ./myscript.sh
cd /any/directory
user@linux ~: ./myscript.sh
user@linux ~: 

Please note that my script is much longer, so I don't want to use a function!

  • see unix.stackexchange.com/a/30964/117549 - "In both cases, the script is run by a separate interpreter process with its own environment separate from that of your shell, whose environment the script cannot affect in any way." – Jeff Schaller Jan 7 '16 at 12:04
  • What does the length of the script have to do with it? Use a function. The longer the script, the more you should use functions anyway, to group things together in logical bits & pieces. – Mat Jan 7 '16 at 12:10

If you want the cd command to bring effect in your current shell then you must run the script in the current shell , because changes in the child shell are not propagated back to the parent shell.

      $ pwd
      $ cat test1
        cd /etc
      $ . test1           #runs test1 in current shell even if its not executable
      $ pwd

Using echo and eval:

Using eval in the parent shell. In shell script echo commands you want to run by parent shell:

echo "cd $filepath"

In parent shell, you can kick the shell script with eval:

  eval `sh foo.sh`


  $ cat test1.sh 
   echo "cd /etc"

  $ eval `sh test1.sh`
  $ pwd
| improve this answer | |
  • I know that, but I want a solution without sourcing the script! – OneStackOverflowUser Jan 7 '16 at 11:54

When you run the scripts it starts separate process, with its own parameters, functions etc. This process inherits environment from parent shell, but after that they are distinct life being. You cannot cd-somewhere in the parent shell from the subshell in the same way like you run send any other command in one process from within another process. In other words there's no magic like

command "run in process 123456"

Now, although you cannot send a command to be executed to a process, you actually can send a signal to a process with kill command. Thus, if you prepare parent shell earlier for this situation you can trap that signal and run some command.

Here is a minimal example:

/home/jimmij $ trap 'cd /tmp' INT
/home/jimmij $ cat myscript.sh
echo Changing parent directory
kill -s SIGINT $PPID

/home/jimmij $ ./myscript.sh
Changing parent directory

/tmp $
| improve this answer | |

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