Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: spawn ENOENT on Windows

Tags:

node.js

I'm on node v4.4.0 and on Windows 10. I'm using bunyan to log my node application.

try {
    var fs = require('fs');
    var path = require('path');
    var spawn = require('child_process').spawn;
    var through = require('through');
} catch (err) {
    throw err;
}

var prettyStream = function () {
    // get the binary directory of bunyan
    var bin = path.resolve(path.dirname(require.resolve('bunyan')), '..', 'bin', 'bunyan');
    console.log(bin); // this outputs C:\www\nodeapp\src\node_modules\bunyan\bin\bunyan, the file does exist

    var stream = through(function write(data) {
        this.queue(data);
    }, function end() {
        this.queue(null);
    });

    // check if bin var is not empty and that the directory exists
    if (bin && fs.existsSync(bin)) {
        var formatter = spawn(bin, ['-o', 'short'], {
            stdio: [null, process.stdout, process.stderr]
        });
        // stream.pipe(formatter.stdin); // <- did this to debug
    }

    stream.pipe(process.stdout); // <- did this to debug

    return stream;
}

The logging spits out in the console due to the fact I used stream.pipe(process.stdout);, i did this to debug the rest of the function.

I however receive the error:

Error: spawn C:\www\nodeapp\src\node_modules\bunyan\bin\bunyan ENOENT
    at exports._errnoException (util.js:870:11)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:178:32)
    at onErrorNT (internal/child_process.js:344:16)
    at nextTickCallbackWith2Args (node.js:442:9)
    at process._tickCallback (node.js:356:17)
    at Function.Module.runMain (module.js:443:11)
    at startup (node.js:139:18)
    at node.js:968:3

I'm guessing this is a Windows error. Anyone have any ideas?

like image 685
basickarl Avatar asked May 26 '16 11:05

basickarl


People also ask

What is Enoent?

It's an abbreviation of Error NO ENTry (or Error NO ENTity), and can actually be used for more than files/directories.

How do you spawn in node JS?

The spawn function launches a command in a new process and we can use it to pass that command any arguments. For example, here's code to spawn a new process that will execute the pwd command. const { spawn } = require('child_process'); const child = spawn('pwd');


2 Answers

Use {shell: true} in the options of spawn

I was hit with this problem recently so decided to add my findings here. I finally found the simplest solution in the Node.js documentation. It explains that:

  • child_process.exec() runs with shell
  • child_process.execFile() runs without shell
  • child_process.spawn() runs without shell (by default)

This is actually why the exec and spawn behave differently. So to get all the shell commands and any executable files available in spawn, like in your regular shell, it's enough to run:

const { spawn } = require('child_process')
const myChildProc = spawn('my-command', ['my', 'args'], {shell: true})

or to have a universal statement for different operating systems you can use

const myChildProc = spawn('my-command', ['my', 'args'], {shell: process.platform == 'win32'})

Side notes:

  1. It migh make sense to use such a universal statement even if one primairly uses a non-Windows system in order to achieve full interoperability
  2. For full consistence of the Node.js child_process commands it would be helpful to have spawn (with shell) and spawnFile (without shell) to reflect exec and execFile and avoid this kind of confusions.
like image 60
Jacek J Avatar answered Sep 29 '22 01:09

Jacek J


I got it. On Windows bunyan isn't recognized in the console as a program but as a command. So to invoke it the use of cmd was needed. I also had to install bunyan globally so that the console could access it.

if (!/^win/.test(process.platform)) { // linux
    var sp = spawn('bunyan', ['-o', 'short'], {
        stdio: [null, process.stdout, process.stderr]
    });
} else { // windows
    var sp = spawn('cmd', ['/s', '/c', 'bunyan', '-o', 'short'], {
        stdio: [null, process.stdout, process.stderr]
    });
}
like image 28
basickarl Avatar answered Sep 29 '22 01:09

basickarl