错误:在Windows上出现 spawn ENOENT 错误

15

我正在使用 Windows 10 操作系统,Node 版本为 v4.4.0,并且使用 bunyan 记录我的 Node 应用程序。

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;
}

由于我使用了stream.pipe(process.stdout)来调试函数,所以日志会在控制台中输出。

然而,我收到了以下错误:

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

我猜这是一个Windows错误。有人有什么想法吗?

6个回答

58

在spawn的选项中使用{shell:true}

最近我遇到了这个问题,所以决定在这里添加我的发现。我最终在Node.js文档中找到了最简单的解决方案。它解释道:

  • child_process.exec() 使用shell运行
  • child_process.execFile() 不使用shell运行
  • child_process.spawn() 默认情况下不使用shell运行

这就是为什么execspawn表现不同的原因。因此,要获取所有可用于spawn的shell命令和任何可执行文件,就像在常规shell中一样,只需运行:

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

或者,为了在不同的操作系统上具有通用性,您可以使用以下代码。
const myChildProc = spawn('my-command', ['my', 'args'], {shell: process.platform == 'win32'})

注:

  1. 即使主要使用非Windows系统,使用这样的通用语句也可能是有意义的,以实现完全的互操作性。
  2. 为了实现 Node.js child_process 命令的完全一致性,有助于使用 spawn(带 shell)和 spawnFile(不带 shell)来反映 execexecFile,避免这种混淆。

23

我懂了。在Windows上,bunyan在控制台中不是作为程序而是作为命令识别。因此需要使用cmd来调用它。我还需要全局安装bunyan,以便控制台可以访问它。

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]
    });
}

7

我使用cross-spawn解决了同样的问题。它允许我在Windows和Mac OS上作为一个常见的命令生成进程。


0
我在Windows中尝试在当前工作目录中执行程序时遇到了同样的问题。我通过在spawn()调用中传递选项{ shell: true, cwd: __dirname }来解决它。然后一切都正常工作,每个参数都作为数组传递(不附加到运行的程序名称)。

0

我认为你会发现它无法找到“bunyun”,但如果你添加“.exe”后缀,它就可以工作了。如果不使用shell选项,它会寻找一个完全匹配的文件名来运行文件本身。

当你使用shell选项时,它会通过匹配可执行扩展名来查找匹配项。因此,你可以通过只附加二进制文件的可执行扩展名来节省一些开销。


-1

我认为,bin路径或其他某些路径可能是错误的。ENOENT = [E]rror [NO] [ENT]ry


有什么想法吗?文件bunyan确实存在:/ - basickarl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接