views:

228

answers:

5

Hey there,

I just found this very usefull shell script here on SO but unfortunately it's not working on Mac OS X 10.5.

This is the script in question(copied it for convenience):

#!/bin/bash
LIMIT=$1
P=$PWD
for ((i=1; i <= LIMIT; i++))
do
    P=$P/..
done
cd $P

I tried to echo $P at the very end and it's returning the right path, but still cd $P doesn't seem to be working.

So I tried to manually enter P="some/path" and cd $P in the terminal and it worked.

I don't get why the same command isn't working in the script. Could it be a security thing?

Any suggestions?

+1  A: 

once the shell script ends it will put you right back in the directory it was executed from. The cd will only effect the cwd of the script process

ennuikiller
+5  A: 

I've had the same issue on Linux, actually, if I understood correctly what I've found after some searching, this is what happens:

The command is launched in a subshell, and in that subshell the path gets changed, you don't see the change because when the script finishes you get back to the starting (parent) shell.

I solved this by putting that useful script in my .bashrc as a function, like this:

up(){
    #code goes here
}

Another option is to source the script every time you launch it but I prefer the first one.

Alberto Zaccagni
That seems promising, but do you know what the mac equivalent of the .bashrc is(a .bashrc doesn't exist in my home directory)? I don't even know what the mac standard shell is :-(
André Hoffmann
if you dont have a .bashrc you can always create it or edit .bash_profile instaed
ennuikiller
Do you have a ~/.bash_profile or a ~/.profile? If yes you can use them . What happens if you just write bash and hit enter at command prompt?
Alberto Zaccagni
I created the .bashrc and it works after typing bash in the console. Yet it would be better if it also worked in the standard terminal.
André Hoffmann
I don't know how is this achieved under OS X, but I think you can use the shell of your choice, in this case bash if you like it...
Alberto Zaccagni
Sweet! It now works using the ~/.profile. Thanks
André Hoffmann
The reason that .bashrc isn't run by default in the OS X terminal is probably because your terminal is opening shells as a login shell.Bash differentiates between shells as being login / or non-login shells, and interactive or non-interactive shells, depending on how it is started up, and this affects the sequence and names of the startup files it will run. The details are in the bash man page, but roughly speaking 'profile' is run for login shells, and '.bashrc' is run for interactive, non-login shells.
cms
+2  A: 

You are only changing the working directory for the copy of the shell that is running the script as an interpreter, not the original shell program that you launched the script from.

For a bash-like shell, in order to run a sequence of commands that operate on the interactive shell session, you can define them as a shell function.

e.g. type the following

up() { LIMIT=$1; P=$PWD; for ((i=1; i <= LIMIT; i++)); do P=$P/..; done; cd $P; }

and you'll define an up command that works the way you intended.

You could put this function definition into a file that is sourced when you login, such as .bashrc, to keep it conveniently defined on login.

cms
+1  A: 

If you want to run the script within the context of your current shell just do one of the following (assuming your shell script is called cdup)

. cdup 3 
source cdup 3

The source command (and its alias .) run the provided script within the context of your current shell, i.e. they do not start a separate sub-shell to run the command so your cd will work as it is within the current shell

Steve Weet
I didn't know about the source command. Thanks!
André Hoffmann
+1  A: 
runarM
Thanks, that's quite useful.
André Hoffmann