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

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.

This question is related to javascript node.js terminal command-line-interface cd

The answer is


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.


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.


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'

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.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to terminal

Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) Can't compile C program on a Mac after upgrade to Mojave Flutter command not found VSCode Change Default Terminal How to switch Python versions in Terminal? How to open the terminal in Atom? Color theme for VS Code integrated terminal How to edit a text file in my terminal How to open google chrome from terminal? Switch between python 2.7 and python 3.5 on Mac OS X

Examples related to command-line-interface

How to change port number in vue-cli project How to change the project in GCP using CLI commands Switch php versions on commandline ubuntu 16.04 Find nginx version? Laravel 5 – Clear Cache in Shared Hosting Server How to open Atom editor from command line in OS X? Is there a way to continue broken scp (secure copy) command process in Linux? Execute a command line binary with Node.js Change working directory in my current shell context when running Node script Is there a way to follow redirects with command line cURL?

Examples related to cd

Change directory command in Docker? Change working directory in my current shell context when running Node script How to cd into a directory with space in the name? How do I find the current directory of a batch file, and then use it for the path? Run cmd commands through Java Equivalent of shell 'cd' command to change the working directory?