views:

1352

answers:

9

This may be too generic a question as is but... I am stumped by trying to move through the directories from within a shell script. I'm not a *nix power user, but I am comfortable working through the command line for most tasks. I'd like to call a script that can move 'me' to a directory instead of just the script process similar to the following:

prompt:> goto lit
where goto is an alias -> goto='./goscript'
and
goscript has some simple code in such as: cd /path to work dirs/lit/user dir
(assuming each user has a directory inside /lit)

I've avoided this issue myself by setting my personal alias' to move to the desired directory, run a script, then return to the original directory. This question was brought to me by a co-worker who uses a similar method, but wanted to make the process more generic so we don't need to create every single alias we need. I thought this would be an easy problem to solve, but I'm stumped as I don't really have a great deal of shell scripting experience ...as of yet.

A: 

You can't. The script has its own copy of the environment, and so it can't change the login shell's environment.

Paul Tomblin
A: 

You can't use cd in a bash script. You could alias the cd and path though.

alias goto='cd /path_to_work/usr/dir'

UPDATE: you would put that line in your .bashrc file and then do

source ~/.bashrc

to create the alias.

Magus
A: 

You can accomplish some simple stuff like this using an alias. For example, I have some aliases that put me into a workspace environment and configure variables for our Makefile system. Here's a real alias I am using as an example. The '&&' will continue executing the commands until one of them fails--in simple scenarios like this, no clean-up is needed, since failure isn't likely.

alias main1='cd ~/code/main1 && export TOP=`pwd` && export DEBUG=1'

If you want to develop a shared library of aliases amongst your co-workers, you can share them over NFS and source the file to be included.

Mitch Haile
A: 

Each script has its own idea of the current working directory. "cd" is not a process but a shell build-in.

The way to do what you want is to create an alias. In csh it will be something like:

alias goto 'cd /path_to_work/\!*/user_dir'

sh/bash have similar alias facilities

Andrew Stein
+5  A: 

You can create a function that is called goto (or whatever) and make sure it is defined in your .bashrc (or you can "source" it from your current shell):

function goto {
    #  the "$USER" part will expand to the current username
    # the "$1" will expand to the first argument to the function ("goto xyz" => $1 is "xyz")
    cd /some-path/lit/$USER/$1
}

Put this in ~/.bashrc or in a separate file and call "source the-file" from your prompt then you can call the function just like any other program:

prompt> goto folder
 cd /some-path/lit/your-user/folder
Isak Savo
+4  A: 

To execute a script in the same environment of your prompt you have to invoke it with .

Say you have the script named up:

cd ..

if you invoke it with . you get:

$> pwd
$> /home/users/rd/proj
$> . up
$> pwd
$> /home/users/rd
Remo.D
The dot is actually equivalent to "source" command. Although at least in my system I have to write ". ./up" instead of just ". up" - othwerwise I'll get error: "bash: ELF: command not found"
Rene Saarsoo
You're right about source. The reason you gat the error is that you don't have . in the path. That's the default behaviour (whose reason I've nver quite understood) for many unix shell.
Remo.D
@Remo.D: the reason is security. It ensures you won't accidentally execute a command from the current directory instead of the "real" command. Imagine a shell script in your home directory called 'ls' whose contents were 'rm -rf /'
Adam Liss
A: 

I tend to have a couple dozen aliases in my .rc that look like this:

alias work='cd /home/foo/work'
alias rails='cd /home/foo/rails'
alias assets='cd /home/foo/rails/assets'

etc.

If that isn't going to work for you, you might be able to use the debug hooks in bash to replace the command line in-place before it is executed - if the 'goto' keyword is the first thing on the line. This will involve googling around for 'trap' in bash, but be forewarned, such incantations do not behave the same on all systems. I wrote up one such experience a few months ago, and you're welcome to the results.

+8  A: 

Even better than using an alias as others have described, check out the CDPATH variable! It's basically equivalent of the PATH functionality, but applied to the cd command.

For example, if I define my CDPATH=${HOME}/subdir, and ~/subdir contains another directory, subsubdir, then I can simply execute:

cd subsubdir

from any directory, and I can navigate the the path as expected.

Here's some more specifics:

http://www.caliban.org/bash/#bashtips

To set the CDPATH variable, add a line to your .bashrc, such as

export CDPATH=${HOME}/subdir
Scott Wegner
+1 for using the right tool for the job ... something I'm trying to teach my kids, who seem to think _everything_ is a hammer.
Adam Liss
Also, if you value your sanity, ensure that the first character in the value of CDPATH is ':' so that when you type 'cd bin' and there is a bin directory in the current directory, that's where you go to.
Jonathan Leffler
+1  A: 

I wasn't a member when I asked this (ironically my anonymous login question has higher flair than my official login questions combined), so I can't close it now - But- The Remo D. et al. answer would be the one that led to the working solution we needed. If anyone with mod powers can close this & select that as the accepted answer, i'd apprediate it.