Reputation: 21531
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?
Upvotes: 12
Views: 18890
Reputation: 9650
(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
Upvotes: 15
Reputation: 1413
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
Upvotes: 21
Reputation: 544
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}`);
});
Upvotes: 1
Reputation: 5166
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.
Upvotes: 2
Reputation: 6378
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.
Upvotes: 17