我正在尝试让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 ......
答案 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");