9

My bash script:

#!/bin/bash
cd /tmp

Before running my script:

pwd: /

After running my script:

pwd: /

After runnig my script trough sourcing it:

pwd: /tmp

How I can stay at the path from the script without sourcing it ?

Cyrus
  • 69,405
  • 13
  • 65
  • 117
astropanic
  • 10,140
  • 17
  • 64
  • 128

6 Answers6

14

You can't. Changes to the current directory only affect the current process.

Ignacio Vazquez-Abrams
  • 699,552
  • 132
  • 1,235
  • 1,283
6

Let me elaborate a little bit on this:

When you run the script, bash creates a new process for it, and changes to the current directory only affect that process.

When you source the script, the script is executed directly by the shell you are running, without creating extra processes, so changes to the current directory are visible to your main shell process.

So, as Ignacio pointed out, this can not be done

Maxim Sloyko
  • 13,143
  • 7
  • 36
  • 47
3

Ignacio is correct. However, as a heinous hack (totally ill advised and this really should get me at least 10 down votes) you can exec a new shell when you're done

#!/bin/bash
...
cd /
exec bash
William Pursell
  • 174,418
  • 44
  • 247
  • 279
  • This will lead to an extra shell running (your original one). Bonus points if you can fix that, too. – sorpigal Dec 16 '10 at 15:34
  • I liked this one, even though you must now type exit twice to close the terminal window. One improvement: exec bash -l (so that your command prompt is reasonable) – Mark Bennett May 08 '13 at 17:56
3

Here's a silly idea. Use PROMPT_COMMAND. For example:

$ export PROMPT_COMMAND='test -f $CDFILE && cd $(cat $CDFILE) && rm $CDFILE'
$ export CDFILE=/tmp/cd.$$

Then, make the last line of your script be 'pwd > $CDFILE'

William Pursell
  • 174,418
  • 44
  • 247
  • 279
2

If you really need this behavior, you can make your script return the directory, then use it somehow. Something like:

#!/bin/bash
cd /tmp
echo $(pwd)

and then you can

cd $(./script.sh)

Ugly, but does the trick in this simple case.

RogerFC
  • 329
  • 3
  • 14
  • I agree - if the user REALLY needs this and cannot achieve this via a function in .bashrc function, the closest thing would be run the external script and then cd to whatever was the return HOWEVER - this implies that the external script cannot have any interaction with the user because you are consuming all of the output. This is why William's answer seems a bit more flexible. mayEb stderr could be used - really need more details from the user about the use case – nhed Mar 13 '11 at 05:11
1

You can define a function to run in the current shell to support this. E.g.

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

I have the above in my ~/.bashrc

pixelbeat
  • 27,785
  • 9
  • 47
  • 57