提问人:laconbass 提问时间:12/29/2014 最后编辑:Communitylaconbass 更新时间:7/21/2023 访问量:735630
如何在节点 .js 上调试“错误:生成 ENOENT”?
How do I debug "Error: spawn ENOENT" on 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)
我可以按照什么程序来修复它?
作者注:此错误的许多问题促使我发布此问题以供将来参考。
相关问题:
- 使用 NODE_ENV=production 的 spawn 函数
- node.js child_process.spawn ENOENT 错误 - 仅在 supervisord 下
- 生成 ENOENT 节点 .js 错误
- https://stackoverflow.com/questions/27603713/nodejs-spawn-enoent-error-on-travis-calling-global-npm-package
- 节点 JS - child_process crunt 任务中生成 ('npm install') 导致 ENOENT 错误
- 运行“工头”任务 致命错误:生成 ENOENT
- 节点 js 中未处理的错误事件 错误:在 errnoException 处生成 ENOENT (child_process.js:975:11)
- 节点 .js SpookyJS:执行 hello .js 时出错
- https://stackoverflow.com/questions/26572214/run-grunt-on-a-directory-nodewebkit
- 使用子进程 NodeJS 运行 exe 文件
- 节点:child_process.spawn 无法在 Java 上运行,即使它在路径中 (ENOENT)
- 使用 NodeJS 生成 ENOENT 错误(与 PYTHON 相关)
- 图像大小调整在 Node.js 中不起作用(部分 .js)(未安装的依赖项)
- npm 安装错误 ENOENT(构建依赖项问题)
- 无法在 Windows 7 上安装 node.js - oracle 模块(构建依赖问题)
- 在 Windows 上使用 nodejs 安装 gulp 时出错(奇怪的情况)
答:
第 1 步:确保以正确的方式调用spawn
首先,查看 child_process.spawn( command, args, options )的文档:
使用给定的命令行参数启动一个新进程。如果省略,则默认为空 Array。
command
args
args
第三个参数用于指定其他选项,默认为:
{ cwd: undefined, env: process.env }
用于指定对新进程可见的环境变量,默认值为 。
env
process.env
确保您没有在命令中放置任何命令
行参数,并且整个生成
调用有效。继续执行下一步。
步骤 2:确定发出错误事件的事件发射器
在源代码中搜索每个调用 ,或 ,即spawn
child_process.spawn
spawn('some-command', [ '--help' ]);
并在那里附加一个“错误”事件的事件侦听器,这样你就会注意到将其抛出为“未处理”的确切事件发射器。调试后,可以删除该处理程序。
spawn('some-command', [ '--help' ])
.on('error', function( err ){ throw err })
;
执行,您应该获取注册“错误”侦听器的文件路径和行号。像这样:
/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
再次执行此步骤,直到它们没有。 在继续下一步之前,必须确定发出错误的侦听器。
第 3 步:确保设置了环境变量$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']);
方案 2 的示例
var env = getEnvKeyValuePairsSomeHow();
// inspect the PATH key on the env object
console.log( env.PATH );
spawn('some-command', ['--help'], { env: env });
缺少 PATH
(即,它未定义
)将导致 spawn
发出 ENOENT
错误,因为除非它是可执行文件的绝对路径,否则无法找到任何路径。command
正确设置 PATH
后,继续下一步。它应该是一个目录,或一个目录列表。最后一种情况是通常的。
第 4 步:确保存在于command
PATH
如果 filename 命令
(即“some-command”)在 PATH
上定义的至少一个目录中不存在,则 Spawn 可能会发出 ENOENT
错误。
找到 的确切位置。在大多数 linux 发行版上,这可以通过带有命令的终端完成。它会告诉你可执行文件的绝对路径(如上所述),或者告诉你是否找不到它。command
which
找到命令时的用法及其输出示例
> which some-command
some-command is /usr/bin/some-command
找不到命令时的示例用法及其输出
> which some-command
bash: type: some-command: not found
未安装的程序是未找到命令的最常见原因。如果需要,请参阅每个命令文档并安装它。
当命令是一个简单的脚本文件时,请确保可以从 PATH
上的目录访问它。如果不是,请将其移动到一个或链接到它。
一旦确定已正确设置并可从中访问,您应该能够在不被抛出的情况下生成子进程。PATH
command
spawn ENOENT
评论
cwd
spawn('some-command', ['--help'], { env: env });
PATH
{ env: { PATH: process.env.PATH } }
shell: true
注意:此错误几乎总是由于命令不存在、工作目录不存在或仅由 Windows 错误引起的。
我发现了一种特别简单的方法来了解以下根本原因:
Error: spawn ENOENT
这个错误的问题是,错误消息中几乎没有信息可以告诉你调用站点在哪里,即找不到哪个可执行文件/命令,特别是当你有一个很大的代码库,有很多生成调用时。另一方面,如果我们知道导致错误的确切命令,那么我们可以按照@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 找不到可执行文件来解决问题的原因。
评论
spawn()
exec()
exec()
就我而言,由于未安装必要的依赖系统资源,我引发了此错误。
更具体地说,我有一个使用 ImageMagick 的 NodeJS 应用程序。尽管安装了 npm 包,但核心 Linux ImageMagick 尚未安装。我做了一个合适的安装ImageMagick,之后一切都很好!
评论
yarn
brew install imagemagick
对于任何可能偶然发现这一点的人,如果所有其他答案都无济于事并且您在 Windows 上,请知道 Windows 上的 spawn 当前存在一个大问题,并且环境变量可能会导致某些调用 spawn
不起作用,具体取决于目标命令的安装方式。PATHEXT
评论
spawn
exec
Windows 解决方案:替换为 node-cross-spawn。例如,在应用.js的开头:spawn
(function() {
var childProcess = require("child_process");
childProcess.spawn = require('cross-spawn');
})();
评论
var spawn = require('cross-spawn');
// Spawn NPM asynchronously var child = spawn('npm', ['list', '-g', '-depth', '0'], { stdio: 'inherit' });
当我尝试从 Debian Linux 系统上的 VS Code 编辑器中调试 node.js 程序时,我遇到了此错误。我注意到同样的事情在 Windows 上运行正常。之前在这里给出的解决方案没有多大帮助,因为我没有编写任何“生成”命令。违规代码可能是由Microsoft编写的,并隐藏在VS Code程序的引擎盖下。
接下来,我注意到 node.js 在 Windows 上被称为 node,但在 Debian(大概在基于 Debian 的系统,如 Ubuntu)上,它被称为 nodejs。所以我创建了一个别名 - 从根终端,我运行
ln -s /usr/bin/nodejs /usr/local/bin/node
这解决了问题。相同或类似的过程可能适用于其他情况,其中您的 node.js 称为 nodejs,但您正在运行一个期望它称为 node 的程序,反之亦然。
@laconbass的回答帮助了我,而且可能是最正确的。
我来这里是因为我错误地使用了 spawn。 举个简单的例子:
这是不正确的:
const s = cp.spawn('npm install -D suman', [], {
cwd: root
});
这是不正确的:
const s = cp.spawn('npm', ['install -D suman'], {
cwd: root
});
这是正确的:
const s = cp.spawn('npm', ['install','-D','suman'], {
cwd: root
});
但是,我建议这样做:
const s = cp.spawn('bash');
s.stdin.end(`cd "${root}" && npm install -D suman`);
s.once('exit', code => {
// exit
});
这是因为只要安装了 Bash,事件就会始终触发,否则,如果我们以第一种方式使用它,如果我们直接启动“npm”,则事件可能会首先触发。cp.on('exit', fn)
cp.on('error', fn)
评论
child_process.exec
shell: true
spawn
我在 Windows 8 上遇到了同样的错误,问题是因为缺少系统路径的环境变量。将“C:\Windows\System32\”值添加到系统 PATH 变量中。
我遇到了同样的问题,但我找到了一种简单的方法来解决它。
如果用户已将程序添加到PATH中,则似乎是错误的(例如,正常的系统命令有效)。spawn()
要解决此问题,您可以使用 which 模块 ():npm install --save which
// Require which and child_process
const which = require('which');
const spawn = require('child_process').spawn;
// Find npm in PATH
const npm = which.sync('npm');
// Execute
const noErrorSpawn = spawn(npm, ['install']);
正如@DanielImfeld所指出的,如果您在选项中指定“cwd”,但给定的目录不存在,则会抛出 ENOENT。
评论
cwd
对于 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'})
对于 Node.js 5.x 及更高版本:
spawn('npm', ['-v'], {stdio: 'inherit', shell: true})
评论
shell: true
确保要执行的模块已安装,如果它不是节点模块,则为命令的完整路径
使用而不是生成来获取更具体的错误消息!require('child_process').exec
例如:
var exec = require('child_process').exec;
var commandStr = 'java -jar something.jar';
exec(commandStr, function(error, stdout, stderr) {
if(error || stderr) console.log(error || stderr);
else console.log(stdout);
});
如果您使用的是 Windows Node,.js 在处理引号时会做一些有趣的工作,这可能会导致您发出一个您知道在控制台中有效的命令,但在 Node 中运行时不起作用。例如,以下操作应有效:
spawn('ping', ['"8.8.8.8"'], {});
但失败了。有一个非常未记录的选项来处理引号/类似的东西,似乎可以解决问题,只要确保将以下内容添加到您的 opts 对象中:windowsVerbatimArguments
const opts = {
windowsVerbatimArguments: true
};
你的命令应该重新开始工作。
spawn('ping', ['"8.8.8.8"'], { windowsVerbatimArguments: true });
评论
我在运行测试用例时也遇到了这个烦人的问题,所以我尝试了很多方法来解决这个问题。但是对我来说有效的方法是从包含主文件的目录运行测试运行程序,其中包括您的nodejs spawn函数,如下所示:
nodeProcess = spawn('node',params, {cwd: '../../node/', detached: true });
例如,此文件名是 test.js,因此只需移动到包含它的文件夹即可。就我而言,它是这样的测试文件夹:
cd root/test/
然后从运行你的测试运行器,在我的情况下是摩卡,所以它会是这样的:
mocha test.js
我浪费了一天多的时间来弄清楚。享受!!
我的解决方案
var spawn = require('child_process').spawn;
const isWindows = /^win/.test(process.platform);
spawn(isWindows ? 'twitter-proxy.cmd' : 'twitter-proxy');
spawn(isWindows ? 'http-server.cmd' : 'http-server');
评论
.cmd
.cmd
我在 Windows 上遇到了这个问题,其中调用并使用完全相同的命令(省略参数)工作正常(所以我知道我的命令已打开),但会给 ENOENT。原来,我只需要附加到我正在使用的命令中:exec
spawn
exec
$PATH
spawn
.exe
import { exec, spawn } from 'child_process';
// This works fine
exec('p4 changes -s submitted');
// This gives the ENOENT error
spawn('p4');
// But this resolves it
spawn('p4.exe');
// Even works with the arguments now
spawn('p4.exe', ['changes', '-s', 'submitted']);
您是否正在更改选项?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',
}
});
如果您在无法修改其源代码的应用程序中遇到此问题,请考虑使用环境变量设置为 来调用它,例如 。这将为您提供在哪个目录中调用了哪些命令行的信息,通常最后一个详细信息是失败的原因。NODE_DEBUG
child_process
NODE_DEBUG=child_process yarn test
评论
只需添加选项即可解决我的问题:shell: true
以下代码在 Windows 上是错误的:
const { spawn } = require('child_process');
const child = spawn('dir');
解决方法:
const { spawn } = require('child_process');
const child = spawn('dir', [], {shell: true});
基于 Node.js 文档(感谢@Boris评论):
请注意:
如果启用了 shell 选项,请不要将未经清理的用户输入传递给 这个函数。可以使用任何包含 shell 元字符的输入 触发任意命令执行。
评论
{ shell: true }
eslint
在任何人花费大量时间调试此问题之前,大多数时候可以通过删除并重新安装软件包来解决。node_modules
要安装:
如果存在锁定文件,则可以使用
yarn install --frozen-lockfile
或
npm ci
恭敬地。如果不是,那么
yarn install
或
npm i
评论
尽管对于某些人来说,这可能是环境路径或其他问题,但我刚刚在 Windows 10 上安装了适用于 Visual Studio Code 的 Latex Workshop 扩展,并在尝试构建/预览 PDF 时看到了此错误。以管理员身份运行 VS Code 为我解决了这个问题。
评论
如何研究引发错误的生成调用:
- 使用 NODE_DEBUG=child_process,积分为 @karl-richter。简单,快速,2019 年 10 月
- 使用包装器装饰
child_process.spawn
,积分为 @jiaji-周。简单、快捷,2015 年 1 月 - 程序长,归功于@laconbass。复杂,时间成本,2014 年 12 月
已知的常见病因
环境问题
- 系统中不存在命令可执行文件(未安装依赖项)。查看 Prominc 的回答
- 命令可执行文件在环境变量指定的目录中不存在。
PATH
- 可执行二进制文件是使用不兼容的库编译的。查看 Danilo-Ramirez 回答
仅限 Windows 的错误/怪癖
- “.cmd”扩展名/外壳:true。查看 Li-Zheng 回答
- 管理员权限。查看 steve's 回答
错误的用法
spawn('command', ['--argument', 'list'], { cwd, env, ...opts })
- 指定的工作目录 () 不存在 ·查看 Leeroy-Brun的回答
opts.cwd
- 命令
中的参数列表spawn('command --wrong --argument list')
String
- 命令字符串中的 Env vars
spawn('ENV_VAR=WRONG command')
- 参数列表指定为
spawn('cmd', '--argument list')
Array
String
- 取消设置环境变量
spawn('cmd', [], { env: { variable } }
PATH
=>spawn('cmd', [], { env: { ...process.env, variable } }
- 指定的工作目录 () 不存在 ·查看 Leeroy-Brun的回答
有 2 个可能的起源:
ENOENT
- 您正在编写的代码
- 您依赖的代码
当 origin 是您依赖的代码时,通常原因是环境问题(或 Windows 怪癖)
评论
在我的情况下删除节点,删除所有 AppData/Roaming/npm 和 AppData/Roaming/npm-cache 并再次安装节点解决了这个问题。
最近我也遇到了类似的问题。
Starting the development server...
events.js:174
throw er; // Unhandled 'error' event
^
Error: spawn null ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
at onErrorNT (internal/child_process.js:415:16)
at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
at Process.ChildProcess._handle.onexit (internal/child_process.js:246:12)
at onErrorNT (internal/child_process.js:415:16)
at process._tickCallback (internal/process/next_tick.js:63:19)
error Command failed with exit code 1.
这是由于 .我有,但它必须是.更改该配置解决了我的问题。.env
BROWSER
BROWSER=null
BROWSER=none
尝试了所有没有任何效果,我的系统有不同的问题。
对我来说,工作解决方案是运行命令: npm config set script-shell “C:\Program Files\git\bin\bash.exe”
评论
npm
child_process.spawn()
我发现的一个案例不在此列表中,但值得添加:
在 Alpine Linux 上,如果可执行文件不兼容,则 Node 将出现 ENOENT 错误。
Alpine 期望 .可执行文件(例如 作为 chromium 的一部分),作为系统调用的包装器进行编译,当被 调用时,ENOENT 将失败。libc
chrome
glibc
spawn
评论
模拟器上的本地开发
请确保在本地安装包。通过更改命令,我得到了一个更详细的错误,并发现我没有安装该软件包。只需运行,检查包是否存在:spawn
exec
brew install imagemagick
我在构建时出现了这个。gulp-jekyll
Powershell
Windows 11
nodejs 10 LTS
, , , ,gulp v3.9.1
ruby 3.1
bundler 2.4.5
jekyll 4.2.2
这里的这行代码是我遇到 和 的问题的原因。ENOENT
spawn
bundle
return cp.spawn('bundle', [
'exec',
'jekyll',
'build',
'--source=app', '--destination=build/development', '--config=_config.yml', '--profile'
], { stdio: 'inherit' })
.on('close', done);
返回了两个错误,故障排除应从此处开始。🤓🧐
events.js:174
throw er; // Unhandled 'error' event
^
Error: spawn bundle ENOENT
没有处理错误事件,因此使用简单的处理将暴露带有调试信息的真正错误:cp.spawn
console.log()
return cp.spawn('bundle', [
'exec',
'jekyll',
'build',
'--source=app', '--destination=build/development', '--config=_config.yml', '--profile'
], { stdio: 'inherit' })
.on('error', (e) => console.log(e))
.on('close', done);
现在,这提供了更多可供调试的信息。
{ Error: spawn bundle ENOENT
errno: 'ENOENT',
code: 'ENOENT',
syscall: 'spawn bundle',
path: 'bundle',
spawnargs:
[ 'exec',
'jekyll',
'build',
'--source=app',
'--destination=build/development',
'--config=_config.yml',
'--profile' ] }
下一步调试是使用 child_process.spawn(command[, args][, options])
的文档。如上所述,将 添加到生成选项中是一个可行的解决方案。这也解决了我的问题。😌nodejs 10 LTS
{ shell: true }
{ stdio: 'inherit', shell: true }
这个解决方案只是一个创可贴,可以重构以处理所有环境,但这超出了如何排除和调试错误的范围。spawn ENOENT
nodejs
可能存在以下情况:您的项目目录中有两个package-lock.json文件(在主文件夹中/在主文件夹中),只需删除意外创建的文件即可。删除生成文件夹,然后再次运行服务器。
评论
下一个:将邮件的所有附件复制到嵌入
评论
exec
spawn( "adb logcat -c" )
spawn( "adb", [ "logcat", "-c" ] )