2

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
#!/bin/bash
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!

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
  • see http://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 07 '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 07 '16 at 12:10

2 Answers2

2

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
      /afs/user/i/ahmad
      $ cat test1
        #!/bin/bash
        cd /etc
      $ . test1           #runs test1 in current shell even if its not executable
      $ pwd
      /etc

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`

Example:

  $ cat test1.sh 
   #!/bin/bash
   echo "cd /etc"

  $ eval `sh test1.sh`
  $ pwd
  /etc
Ijaz Ahmad
  • 7,202
1

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
#!/bin/bash
echo Changing parent directory
kill -s SIGINT $PPID

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

/tmp $
jimmij
  • 47,140