events.js:72
throw er; // Unhandled 'error' event
^
Error: spawn ENOENT
at errnoException (child_process.js:1000:11)
at Process.ChildProcess._handle.onexit (child_process.js:791:34)
作者注:这个错误的许多问题鼓励我张贴这个问题,以供将来参考。
相关问题:
注意:这个错误几乎总是因为命令不存在,因为工作目录不存在,或者是因为Windows仅有的bug造成的。
我找到了一个特别简单的方法来了解以下问题的根本原因:
Error: spawn ENOENT
这个错误的问题是,错误消息中很少有信息可以告诉您调用站点在哪里,即没有找到哪个可执行/命令,特别是当您有一个很大的代码库,其中有很多spawn调用时。另一方面,如果我们知道导致错误的确切命令,那么我们就可以按照@laconbass的答案来解决问题。
我找到了一种非常简单的方法来发现是哪个命令导致了问题,而不是像@Laconbass的回答中建议的那样在代码中到处添加事件监听器。关键思想是用包装器包装原始的spawn调用,该包装器打印发送到spawn调用的参数。
下面是包装器函数,将其放在index.js
或服务器启动脚本的顶部。
(function() {
var childProcess = require("child_process");
var oldSpawn = childProcess.spawn;
function mySpawn() {
console.log('spawn called');
console.log(arguments);
var result = oldSpawn.apply(this, arguments);
return result;
}
childProcess.spawn = mySpawn;
})();
那么下次运行应用程序时,在未捕获的异常消息之前,您将看到如下内容:
spawn called
{ '0': 'hg',
'1': [],
'2':
{ cwd: '/* omitted */',
env: { IP: '0.0.0.0' },
args: [] } }
这样,您就可以很容易地知道实际执行的是哪个命令,然后您就可以找到nodejs为什么找不到可执行文件来修复问题。
首先,查看child_process.spawn(命令、参数、选项)的文档:
使用给定的命令
启动新进程,命令行参数在args
中。如果省略,args
默认为空数组。
第三个参数用于指定附加选项,默认为:
{cwd:undefined,env:process.env}
使用env
指定对新进程可见的环境变量,默认值为process.env
。
确保您没有在command
中放入任何命令行参数,并且整个spawn
调用有效。继续下一步。
在源代码上搜索对spawn
或child_process.spawn
的每次调用,即。
spawn('some-command', [ '--help' ]);
并为“error”事件附加一个事件侦听器,这样您就会注意到将其抛出为“unhandled”的事件发射器。调试后,可以移除该处理程序。
spawn('some-command', [ '--help' ])
.on('error', function( err ){ throw err })
;
执行,您应该得到文件路径和行号,您的'error'侦听器是在那里注册的。类似于:
/file/that/registers/the/error/listener.js:29
throw err;
^
Error: spawn ENOENT
at errnoException (child_process.js:1000:11)
at Process.ChildProcess._handle.onexit (child_process.js:791:34)
如果前两行是静止的
events.js:72
throw er; // Unhandled 'error' event
再次执行此步骤,直到它们不是。在继续下一步之前,必须标识发出错误的侦听器。
有两种可能的情况:
spawn
行为,因此子进程环境将与process.env
相同。env
对象明确地传递给options
参数的spawn
。在这两种情况下,都必须检查生成的子进程将使用的环境对象上的path
键。
场景1示例
// inspect the PATH key on process.env
console.log( process.env.PATH );
spawn('some-command', ['--help']);
场景2示例
var env = getEnvKeyValuePairsSomeHow();
// inspect the PATH key on the env object
console.log( env.PATH );
spawn('some-command', ['--help'], { env: env });
缺少path
(即undefined
)将导致spawn
发出enoent
错误,因为除非是可执行文件的绝对路径,否则不可能找到任何命令
。
正确设置path
后,继续下一步。它应该是一个目录,或目录列表。最后一种情况是常见的。
如果文件名命令
(即'some-command')在path
上定义的至少一个目录中不存在,则Spawn可能会发出enoent
错误。
找到命令
的确切位置。在大多数linux发行版上,这可以通过whice
命令从终端完成。它将告诉您可执行文件的绝对路径(如上),或者告诉您是否未找到该文件。
找到命令时which及其输出的用法示例
> which some-command
some-command is /usr/bin/some-command
未找到命令时which及其输出的用法示例
> which some-command
bash: type: some-command: not found
未安装的程序是not found命令最常见的原因。如果需要,请参阅每个命令文档并安装它。
当命令是一个简单的脚本文件时,确保可以从路径
上的目录访问它。如果不是,要么把它移动到一个,要么做一个链接到它。
一旦您确定path
设置正确,并且command
可以从其中访问,您就应该能够生成您的子进程,而不会抛出spawnenoent
。