46
var sys = require('sys'),
    exec = require('child_process').exec;

exec("cd /home/ubuntu/distro", function(err, stdout, stderr) {
        console.log("cd: " + err + " : "  + stdout);
        exec("pwd", function(err, stdout, stderr) {
            console.log("pwd: " + err + " : " + stdout);
            exec("git status", function(err, stdout, stderr) {
                console.log("git status returned " ); console.log(err);
            })
        })
    })

cd: null :

pwd: null : /

git status returned 
{ [Error: Command failed: fatal: Not a git repository (or any of the parent directories): .git ] killed: false, code: 128, signal: null }

nodeJS exec does not work for "cd " shell cmd. as you see below, pwd works, git status is trying to work but fails because it is not executed in a git directory, but cd cmd fails stopping further successful execution of other cmds. Tried in nodeJS shell as well as nodeJS+ExpressJS webserver.

user1447121
  • 2,861
  • 4
  • 22
  • 23

3 Answers3

87

Each command is executed in a separate shell, so the first cd only affects that shell process which then terminates. If you want to run git in a particular directory, just have Node set the path for you:

exec('git status', {cwd: '/home/ubuntu/distro'}, /* ... */);

cwd (current working directory) is one of many options available for exec.

icktoofay
  • 126,289
  • 21
  • 250
  • 231
  • looks don't work: I execute antoher .sh file, inside this .sh file I have 'node ./myscript,js' and give 'cannot find module' showing the original path, and not the path given in 'cwd' – stackdave May 19 '18 at 06:40
  • @stackdave: This ought to work. If you cannot get it to work, you can open another question with more information about what you are doing specifically, ideally with a small set of short files to reproduce it. – icktoofay Jul 20 '18 at 06:13
7

Rather than call exec() multiple times. Call exec() once for multiple commands

Your shell IS executing cd but it's just that each shell throws away it's working directory after it's finished. Hence you're back at square one.

In your case, you don't need to call exec() more than once. You can make sure your cmd variable contains multiple instructions instead of 1. CD will work in this case.

var cmd =  `ls
cd foo
ls`

var exec =  require('child_process').exec;

exec(cmd, function(err, stdout, stderr) {
        console.log(stdout);
})

Note: This code should work on Linux but not Windows. See here

Community
  • 1
  • 1
Cameron
  • 2,805
  • 3
  • 31
  • 45
6

It is working. But then it is throwing the shell away. Node creates a new shell for each exec.

Here are options that can help: http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback

000
  • 26,951
  • 10
  • 71
  • 101