lac*_*ass 309 debugging error-handling spawn child-process node.js
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)
Run Code Online (Sandbox Code Playgroud)
作者说明:此错误的许多问题鼓励我发布此问题以供将来参考.
相关问题:
小智 215
我找到了一种特别简单的方法来了解其根本原因:
Error: spawn ENOENT
Run Code Online (Sandbox Code Playgroud)
这个错误的问题是,错误消息中几乎没有信息告诉你调用站点在哪里,即找不到哪个可执行文件/命令,特别是当你有一个很大的代码库,那里有大量的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;
})();
Run Code Online (Sandbox Code Playgroud)
然后,下次运行应用程序时,在未捕获的异常消息之前,您将看到类似的内容:
spawn called
{ '0': 'hg',
'1': [],
'2':
{ cwd: '/* omitted */',
env: { IP: '0.0.0.0' },
args: [] } }
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以轻松地知道实际执行了哪个命令,然后您可以找出为什么nodejs找不到可执行文件来解决问题.
lac*_*ass 110
spawn被称为正确的方式首先,查看child_process.spawn(command,args,options)的文档:
使用给定的
command命令行参数启动一个新进程args.如果省略,则args默认为空数组.第三个参数用于指定其他选项,默认为:
{ cwd: undefined, env: process.env }使用
env指定的环境变量,这将是新的过程可见,默认为process.env.
确保您没有输入任何命令行参数,command并且整个spawn调用有效.继续下一步.
搜索每个调用的源代码spawn,或者child_process.spawn,即
spawn('some-command', [ '--help' ]);
Run Code Online (Sandbox Code Playgroud)
并在那里附加一个'error'事件的事件监听器,这样你就会注意到将它作为'Unhandled'抛出的确切事件发射器.调试后,可以删除该处理程序.
spawn('some-command', [ '--help' ])
.on('error', function( err ){ throw err })
;
Run Code Online (Sandbox Code Playgroud)
执行,你应该得到你的'错误'监听器注册的文件路径和行号.就像是:
/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)
Run Code Online (Sandbox Code Playgroud)
如果前两行仍然是
events.js:72
throw er; // Unhandled 'error' event
Run Code Online (Sandbox Code Playgroud)
再做这一步,直到他们不这样做.在继续下一步之前,您必须识别发出错误的侦听器.
$PATH已设置环境变量有两种可能的情况:
spawn行为,因此子进程环境将是相同的process.env.env对象spawn的options参数.在这两种情况下,您都必须检查PATH生成的子进程将使用的环境对象上的键.
方案1的示例
// inspect the PATH key on process.env
console.log( process.env.PATH );
spawn('some-command', ['--help']);
Run Code Online (Sandbox Code Playgroud)
方案2的示例
var env = getEnvKeyValuePairsSomeHow();
// inspect the PATH key on the env object
console.log( env.PATH );
spawn('some-command', ['--help'], { env: env });
Run Code Online (Sandbox Code Playgroud)
缺少PATH(即,它undefined)将导致spawn发出ENOENT错误,因为command除非它是可执行文件的绝对路径,否则将无法找到任何错误.
如果PATH设置正确,请继续执行下一步.它应该是目录或目录列表.最后一种情况是通常的.
command存在于中定义的目录中PATHENOENT如果文件名command(即'some-command')在至少一个定义的目录中不存在,则Spawn可能会发出错误PATH.
找到确切的地方command.在大多数Linux发行版中,这可以通过which命令终端来完成.它将告诉您可执行文件的绝对路径(如上所述),或告诉您是否找不到它.
找到命令时的示例用法及其输出
> which some-command
some-command is /usr/bin/some-command
Run Code Online (Sandbox Code Playgroud)
未找到命令时的示例用法及其输出
> which some-command
bash: type: some-command: not found
Run Code Online (Sandbox Code Playgroud)
安装错误的程序是找不到命令的最常见原因.如果需要,请参阅每个命令文档并进行安装.
当命令是一个简单的脚本文件时,确保它可以从一个目录访问PATH.如果不是,请将其移至一个或链接到它.
一旦确定PATH已正确设置command并可从中访问,您应该能够在不spawn ENOENT抛出的情况下生成子进程.
ash*_*deh 27
在 Windows 中,只需添加shell: true选项即可解决我的问题:
不正确:
const { spawn } = require('child_process');
const child = spawn('dir');
Run Code Online (Sandbox Code Playgroud)
正确的:
const { spawn } = require('child_process');
const child = spawn('dir', [], {shell: true});
Run Code Online (Sandbox Code Playgroud)
Nil*_*zor 26
Windows解决方案:替换spawn为node-cross-spawn.例如,在app.js的开头就像这样:
(function() {
var childProcess = require("child_process");
childProcess.spawn = require('cross-spawn');
})();
Run Code Online (Sandbox Code Playgroud)
Ale*_*lls 26
@ laconbass的回答对我有帮助,可能是最正确的.
我来到这里是因为我错误地使用了spawn.举个简单的例子:
这是不正确的:
const s = cp.spawn('npm install -D suman', [], {
cwd: root
});
Run Code Online (Sandbox Code Playgroud)
这是不正确的:
const s = cp.spawn('npm', ['install -D suman'], {
cwd: root
});
Run Code Online (Sandbox Code Playgroud)
这是对的:
const s = cp.spawn('npm', ['install','-D','suman'], {
cwd: root
});
Run Code Online (Sandbox Code Playgroud)
但是,我建议这样做:
const s = cp.spawn('bash');
s.stdin.end(`cd "${root}" && npm install -D suman`);
s.once('exit', code => {
// exit
});
Run Code Online (Sandbox Code Playgroud)
这是因为cp.on('exit', fn)只要安装了bash,事件就会一直触发,否则cp.on('error', fn),如果我们直接启动'npm',如果我们以第一种方式使用它,事件可能会先触发.
Li *_*eng 18
对于Windows上的ENOENT,https://github.com/nodejs/node-v0.x-archive/issues/2318#issuecomment-249355505修复它.
例如,用以下代码替换spawn('npm',[' - v'],{stdio:'inherit'}):
对于所有node.js版本:
spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['-v'], {stdio: 'inherit'})
Run Code Online (Sandbox Code Playgroud)对于node.js 5.x及更高版本:
spawn('npm', ['-v'], {stdio: 'inherit', shell: true})
Run Code Online (Sandbox Code Playgroud)Ale*_*pin 17
对于任何可能偶然发现这一点的人来说,如果所有其他答案都没有用,并且你在Windows上,那么就知道Windows和环境变量目前存在一个大问题spawnPATHEXT,可能会导致某些调用产生不起作用,具体取决于方式目标命令已安装.
lac*_*ass 17
child_process.spawn,感谢@jiaji-zhou。简单、快速,2015 年 1 月环境问题
PATH环境变量指定的目录中。仅限 Windows 的错误/怪癖
错误spawn('command', ['--argument', 'list'], { cwd, env, ...opts })用法
opts.cwd) 不存在 ·见leeroy-brun 的回答String spawn('command --wrong --argument list')spawn('ENV_VAR=WRONG command')Array指定为String spawn('cmd', '--argument list')PATH变量spawn('cmd', [], { env: { variable } }spawn('cmd', [], { env: { ...process.env, variable } }有 2 个可能的起源
ENOENT:
- 您正在编写的代码
- 你依赖的代码
当来源是您依赖的代码时,通常的原因是环境问题(或 Windows 怪癖)
在任何人花费大量时间调试此问题之前,大多数情况下可以通过删除node_modules和重新安装软件包来解决。
如果存在锁定文件,您可能会使用
yarn install --frozen-lockfile
Run Code Online (Sandbox Code Playgroud)
或者
npm ci
Run Code Online (Sandbox Code Playgroud)
分别。如果不是那么
yarn install
Run Code Online (Sandbox Code Playgroud)
或者
npm i
Run Code Online (Sandbox Code Playgroud)
在我的情况下,由于没有安装必要的依赖系统资源,我得到了这个错误.
更具体地说,我有一个使用ImageMagick的NodeJS应用程序.尽管安装了npm软件包,但未安装核心Linux ImageMagick.我做了一个apt-get来安装ImageMagick,之后一切都很棒!
env选项吗?然后看看这个答案。
我试图生成一个节点进程和 TIL,你应该在生成时传播现有的环境变量,否则你会丢失PATH环境变量和其他可能的重要变量。
这对我来说是修复:
const nodeProcess = spawn('node', ['--help'], {
env: {
// by default, spawn uses `process.env` for the value of `env`
// you can _add_ to this behavior, by spreading `process.env`
...process.env,
OTHER_ENV_VARIABLE: 'test',
}
});
Run Code Online (Sandbox Code Playgroud)
如果您在无法修改其源的应用程序中遇到此问题,请考虑将环境变量设置NODE_DEBUG为child_process,例如 来调用它NODE_DEBUG=child_process yarn test。这将为您提供在哪个目录中调用了哪些命令行的信息,并且通常最后的详细信息是失败的原因。
| 归档时间: |
|
| 查看次数: |
342887 次 |
| 最近记录: |