Spawn on Node JS (Windows Server 2012)
Asked Answered
O

5

12

When I run this through Node:

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

ls = spawn('ls', ['C:\\Users']);

ls.on('error', function (err) {
  console.log('ls error', err);
});

ls.stdout.on('data', function (data) {
    console.log('stdout: ' + data);
});

ls.stderr.on('data', function (data) {
    console.log('stderr: ' + data);
});

ls.on('close', function (code) {
    console.log('child process exited with code ' + code);
});

I get the following error:

ls error { [Error: spawn ENOENT] code: 'ENOENT', errno: 'ENOENT', syscall: 'spawn' }
child process exited with code -1

On Windows Server 2012. Any ideas?

Occurrence answered 20/8, 2013 at 11:46 Comment(0)
I
15

(Firstly, does ls actually exist on windows?)

I had a similar issue spawning child processes a little while back and it took me ages to figure out the correct way of doing it.

Here's some example code:

var spawn = require('child_process').spawn;
var cp = spawn(process.env.comspec, ['/c', 'command', '-arg1', '-arg2']);
 
cp.stdout.on("data", function(data) {
    console.log(data.toString());
});
 
cp.stderr.on("data", function(data) {
    console.error(data.toString());
});

Have a look at this ticket for an explanation of the issue: https://github.com/joyent/node/issues/2318

[Updated 25/12/2022] As per Gorky's answer, just set shell: true

Irvingirwin answered 20/8, 2013 at 12:2 Comment(0)
S
21

As of node 8 per document, you need to set shell option to true (which is false by default).

spawn('dir', [], { shell: true })

Documentation here

Schnurr answered 19/7, 2018 at 8:21 Comment(2)
This is the newest and best answer IMHO.Ewall
It is the best answer because it covers all of the others' answers. In fact, shell: true uses process.env.comspec and falls back to cmd /c on windows and uses /bin/sh on unix systems.Fraternize
S
17

As badsyntax pointed out, ls doesn't exist on windows as long as you didn't create an alias. You will use 'dir'. The difference is dir is not a program, but a command in windows shell (which is cmd.exe), So you would need to run 'cmd' with arguments to run dir and output the stream.

var spawn = require('child_process').spawn
spawn('cmd', ['/c', 'dir'], { stdio: 'inherit'})

By using 'inherit', the output will be piped to the current process.

Sebrinasebum answered 27/1, 2014 at 21:6 Comment(0)
I
15

(Firstly, does ls actually exist on windows?)

I had a similar issue spawning child processes a little while back and it took me ages to figure out the correct way of doing it.

Here's some example code:

var spawn = require('child_process').spawn;
var cp = spawn(process.env.comspec, ['/c', 'command', '-arg1', '-arg2']);
 
cp.stdout.on("data", function(data) {
    console.log(data.toString());
});
 
cp.stderr.on("data", function(data) {
    console.error(data.toString());
});

Have a look at this ticket for an explanation of the issue: https://github.com/joyent/node/issues/2318

[Updated 25/12/2022] As per Gorky's answer, just set shell: true

Irvingirwin answered 20/8, 2013 at 12:2 Comment(0)
N
2

There are already two working answers to this question, but I would like to mention one more and clarify something.

If you are not planning to return a lot of data (more than 200kB) from your command, you can use exec instead of spawn and more elegantly write:

exec('dir [possible arguments]', (err, stdout, stderr) => {
    console.log(`stdout: ${stdout}`)
})

Read about difference between spawn and exec. to make sure it fits your needs.

As for the clarifications, there is no need to pass {stdio: 'inherit'} to spawn because it creates the pipes by default. from the documentation:

By default, pipes for stdin, stdout and stderr are established between the parent Node.js process and the spawned child. It is possible to stream data through these pipes in a non-blocking way. Note, however, that some programs use line-buffered I/O internally. While that does not affect Node.js, it can mean that data sent to the child process may not be immediately consumed.

Nasal answered 21/10, 2016 at 15:43 Comment(0)
W
1

Hi following code worked for me..

const spawn = require('child_process').spawn;
const bat = spawn('cmd.exe', ['/c','calc.exe']);

bat.stdout.on('data', (data) => {
  console.log(data);
});

bat.stderr.on('data', (data) => {
  console.log(data);
});

bat.on('closed', (code) => {
 alert(`Child exited with code ${code}`);
});
Whereat answered 7/12, 2016 at 10:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.