使用nodejs的spawn会导致“unknown option - ”和“[Error:spawn ENOENT]”错误

时间:2013-07-07 21:53:26

标签: node.js exec spawn

我正在尝试让spawn影响rm -rf node_modules后跟npm install(在Windows 7上; n x命令由透明安装的CygWin提供。所有 n x命令在命令行上解析就好了。

我最初使用exec进行此操作,但是想要在发生时捕获stdout / stderr信息,所以我想我会使用spawn,并重写代码以使用它。但是,这会破坏一切。

重写的rm命令变为:

var spawn = require("child_process").spawn,
    child = spawn("rm", ["-rf", "node_modules"]);
child.stdout.on('data', function (data) { console.log(data.toString()); });
child.stderr.on('data', function (data) { console.log(data.toString()); });
child.on('error', function() { console.log(arguments); });

但是,运行此命令会产生以下错误:

rm: unknown option -- ,

Try `rm --help' for more information.

重写的npm命令变为:

var spawn = require("child_process").spawn,
    child = spawn("npm", ["install"]);
child.stdout.on('data', function (data) { console.log(data.toString()); });
child.stderr.on('data', function (data) { console.log(data.toString()); });
child.on('error', function() { console.log(arguments); });

但是,运行此命令会产生以下错误:

{
  '0': {
    [Error: spawn ENOENT]
    code: 'ENOENT',
    errno: 'ENOENT',
    syscall: 'spawn'
  }
}

如何使用exec使spawn运行相同的命令,而不会在整个地方抛出错误?为什么这不起作用?阅读API http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options,似乎表明这正是人们应该如何使用spawn ......

3 个答案:

答案 0 :(得分:63)

经过大量尝试不同的事情,我终于看看Windows上的“npm”实际上是什么,结果是一个名为npm的bash脚本,以及一个windows-native批处理脚本叫npm.cmd(不知道为什么它是.cmd,应该是.bat,但你有它)。 Windows的命令解析器将看到npm,注意它不是可执行文件,请参阅npm.cmd,然后注意到IS是可执行文件,然后将使用它。当你在终端时这很有用,但是spawn()不会做任何这样的解决方案:传递它npm会使它失败,因为它不是可执行文件。然而,将它作为命令传递npm.cmd可以正常工作。

(另外,不确定为什么rm之前失败了,因为它实际上正常工作而没有我可以告诉的任何更改。可能误读了作为问题的一部分,而实际上它不是。)

所以:如果你遇到spawn在Windows中说ENOENT,当你试图触发的命令在普通命令提示符下工作时,找出你正在调用的命令是否是真正的可执行文件,或者是否存在.bat / .cmd文件,命令提示符将“帮助”为您运行。如果是这样,那就产生了。

修改

由于这篇文章仍然有所提升,确保命令始终有效的一个好方法是根据process.platform引导它,对于Windows来说它是win32

var npm = (process.platform === "win32" ? "npm.cmd" : "npm"),
    child = spawn(npm, ["install", ...]);
...

答案 1 :(得分:0)

我认为这可能是某种cygwin陷阱。我正在运行Ubuntu 12.04并试图复制你的问题,但它对我来说效果很好。简而言之,我没有看到你做错了什么。

如果它抱怨该选项,可能会将其分成多个选项,如下所示:

child = spawn("rm", ["-r", "-f", "node_modules"]);

这是一种冰雹玛丽,但也适用于我的Ubuntu 12.04。您可能会尝试删除单个文件,看看是否得到同样的东西。

child = spawn("rm", ["/home/username/Desktop/TestFile"]);

如果仍然失败,那么你知道你正在反对一些疯狂的事情。

您甚至可以尝试执行不带参数的命令:

child = spawn("ls");

如果仍然失败,那么你根本不可能完成工作,这将是我的猜测,并感激至少exec正在工作。

对你的答案并不多,但就像我说的那样,我看不到你做错了什么。

此外,我没有看到你的npm命令是如何工作的,因为你没有指定安装什么,但是说,它失败的方式不同于我看到它失败了如果我使用同样的命令。 。 。我看到很多stderr输出,而不是整体错误。

BTW,我正在运行节点v0.8.21。您可以按节点-v查询。如果你正在运行另一个版本,可以尝试0.8.21。

答案 2 :(得分:-1)

使用完整路径进行处理,例如:

var cmd = require('child_process').spawn("C:\\windows\\system32\\cmd.exe");