Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've read this question and answer, but it doesn't quit fit my problem, even tho it's similar.

I'm writing a script (called cpj) that will launch one of my current projects. I have about 5 of them. When I type

$ cpj blah

I want the current working directory to change to the blah project directory (which I hold in $PROJDIR) and I want emacsclient to open the main file for that project (which I hold in $MAINFILE).

The question I cited says that you can't directly change the environment of the shell running the script, but you can source a script and it will do so.

To test this I wrote a shell script (called chcwd) which has one line:

cd $1

If, from the command line I do:

$ . chcwd $PROJDIR

my current working directory will change as I desire. If, on the other hand, from my cpj script, I have the same line:

. chcwd $PROJECT

it will not change the current working directory of the shell. I realize that I'm running 2 scripts (cpj and then chcwd), and so creating 2 shells, but I see no way to get done what I want. Can anyone show me how to accomplish my goal?

share|improve this question

2 Answers 2

up vote 7 down vote accepted

You can't have your cake an eat it two. The two things happening here are executing a script in a new shell and importing lines of script to be run in the current shell. By using the dot operator (which is an alias for the source command) you are actually running the code in your current shell. If your code chooses to cd, when it's done you will be left in the new directory.

If on the other hand you want to execute a program (or script, it doesn't matter), that program will be launched as a sub-process. In the case of shell scripts a new shell will be opened and the code run inside it. Any cd action taken will change the current working directory for that shell, effective for any commands to follow. When the job finishes the shell will exit, leaving you back in your original (and unmodified) shell.

That's just the way it is. If it's something you use a lot and you want it's effects to be left behind in your current shell, perhaps you could write your "script" as a shell function instead and save it in your ~/.profile or other shell rc file.

function cpj() {
    # code here
    cd /path/$1
    emacs file_name
}
share|improve this answer
    
Caleb, thx for your input. I like your pun. Your first paragraph restates what I said in my question admirably. Your second paragraph restates what was said in the question I cited quite well. Your third paragraph is exactly and precisely what I was looking for! Thanks dude. –  bev Jun 10 '11 at 1:09

I have similar script written for my personal use. There is a very easy trick to achieve change working directory inside a script. First just write your script, in.ex.:

#!/bin/bash

case $1 in
     project1) cd /home/me/work/customer1/project1
     ;;
     project2) cd /home/me/work/customer2/project1
     ;;
     project3) cd /home/me/work/customer3/project2
     ;;
     project4) cd /home/me/work/customer4/project5
     ;;
     *) echo "Usage: cdto cd_profile_name"
     ;;
esac

Now lets assume the script is called 'cdto'. To make it working you have to source it in the current shell, what can be achieved by 'source' or '.' command (both are the same). In ex.:

. cdto project1

Now to make it more convenient:

  1. Copy 'cdto' script to a 'bin' directory of your account (in. ex. /home/johnsmith/bin - create it if not exists). Check your PATH variable to ensure the 'bin' directory is included:

    echo $PATH

If not, edit your .profile file and add:

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
  1. Add an alias to your .bashrc or .bash_aliases file:

    alias cdto='. cdto'

And it's done. After next login or when you open a new terminal you could just use in.ex.:

cdto project1

Enjoy :-)

Sebastian Piech

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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