Change working directory in my current shell context when running Node script

131,386

Solution 1

The correct way to change directories is actually with process.chdir(directory). Here's an example from the documentation:

console.log('Starting directory: ' + process.cwd());
try {
  process.chdir('/tmp');
  console.log('New directory: ' + process.cwd());
}
catch (err) {
  console.log('chdir: ' + err);
}

This is also testable in the Node.js REPL:

[monitor@s2 ~]$ node
> process.cwd()
'/home/monitor'
> process.chdir('../');
undefined
> process.cwd();
'/home'

Solution 2

There is no built-in method for Node to change the CWD of the underlying shell running the Node process.

You can change the current working directory of the Node process through the command process.chdir().

var process = require('process');
process.chdir('../');

When the Node process exists, you will find yourself back in the CWD you started the process in.

Solution 3

What you are trying to do is not possible. The reason for this is that in a POSIX system (Linux, OSX, etc), a child process cannot modify the environment of a parent process. This includes modifying the parent process's working directory and environment variables.

When you are on the commandline and you go to execute your Node script, your current process (bash, zsh, whatever) spawns a new process which has it's own environment, typically a copy of your current environment (it is possible to change this via system calls; but that's beyond the scope of this reply), allowing that process to do whatever it needs to do in complete isolation. When the subprocess exits, control is handed back to your shell's process, where the environment hasn't been affected.

There are a lot of reasons for this, but for one, imagine that you executed a script in the background (via ./foo.js &) and as it ran, it started changing your working directory or overriding your PATH. That would be a nightmare.

If you need to perform some actions that require changing your working directory of your shell, you'll need to write a function in your shell. For example, if you're running Bash, you could put this in your ~/.bash_profile:

do_cool_thing() {
  cd "/Users"
  echo "Hey, I'm in $PWD"
}

and then this cool thing is doable:

$ pwd
/Users/spike
$ do_cool_thing
Hey, I'm in /Users
$ pwd
/Users

If you need to do more complex things in addition, you could always call out to your nodejs script from that function.

This is the only way you can accomplish what you're trying to do.

Solution 4

Short answer: no (easy?) way, but you can do something that serves your purpose.

I've done a similar tool (a small command that, given a description of a project, sets environment, paths, directories, etc.). What I do is set-up everything and then spawn a shell with:

spawn('bash', ['-i'], {
  cwd: new_cwd,
  env: new_env,
  stdio: 'inherit'
});

After execution, you'll be on a shell with the new directory (and, in my case, environment). Of course you can change bash for whatever shell you prefer. The main differences with what you originally asked for are:

  • There is an additional process, so...
  • you have to write 'exit' to come back, and then...
  • after existing, all changes are undone.

However, for me, that differences are desirable.

Solution 5

Try this code:

const dirPath = path.join(__dirname, foldername);
process.chdir(dirPath);
Share:
131,386
Jonovono
Author by

Jonovono

Updated on July 20, 2021

Comments

  • Jonovono
    Jonovono almost 3 years

    I am trying to change the working directory of my Node.js script when it is run from a bin script. I have something like the following:

    #!/usr/bin/env node
    process.chdir('/Users')
    

    When I then run this file with ./bin/nodefile, it exits, but the working directory of the current shell context has not changed. I have also tried shelljs, but that does not work either.

    What is the best way to do this? I understand it's working but it's just in a separate process.

  • Jonovono
    Jonovono over 10 years
    Oops. Ya, that is the command I am actually using. However, when I use it in a simple script it still does not seem to work (once the script exits I am still in the old directory) If I call process.cwd() it says I am in the directory I should be but my terminal if I call pwd says I am in something otherwise. Because it's a different process?
  • hexacyanide
    hexacyanide over 10 years
    The method changes the current working directory of the process, not the shell. As far as I know, changing the external cwd of a running process is quite complex and isn't recommended. What is your reason for wanting to do this?
  • Jonovono
    Jonovono over 10 years
    Hmm. Ok thanks. Well the reason I want to do this is because I am making a terminal app for organising my projects. So basically I want to be able to list my projects and easily change the current shell location to that. Now that I think about it, I am going to look into how z (github.com/rupa/z) does this. Although that is done in bash. I could perhaps do this in applescript?
  • EugenSunic
    EugenSunic almost 4 years
    @hexacyanide thanks for adding was bothering because the changes were not aligned