Shell – Changing Current Working Directory with a Script

cd-commandshell

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?

Best Answer

You can't have your cake an eat it too. 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.

If it's something you use a lot and you want its 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
}
Related Question