Как отладить "Ошибка: вызвать ENOENT" на 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)
Какую процедуру я могу выполнить, чтобы исправить ее?
Примечание автора.. Многие проблемы с этой ошибкой побудили меня опубликовать этот вопрос для будущих ссылок.
Связанные вопросы:
Ответы
Ответ 1
ПРИМЕЧАНИЕ. Эта ошибка почти всегда возникает из-за того, что команда не существует, потому что рабочий каталог не существует или из-за ошибки только для Windows.
Я нашел очень простой способ понять причину:
Error: spawn ENOENT
Проблема этой ошибки в том, что в сообщении об ошибке действительно мало информации, чтобы сказать вам, где находится сайт вызова, т.е. какой исполняемый файл/команда не найден, особенно если у вас большая кодовая база, где много вызовов спавна. С другой стороны, если мы знаем точную команду, которая вызывает ошибку, тогда мы можем следовать @laconbass 'answer, чтобы решить проблему.
Я нашел очень простой способ определить, какая команда вызывает проблему, вместо добавления прослушивателей событий в вашем коде, как предложено в ответе @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 не может найти исполняемый файл для решения проблемы.
Ответ 2
Шаг 1: Убедитесь, что spawn
называется правильным способом
Сначала просмотрите docs для child_process.spawn(команда, args, options):
Запускает новый процесс с заданным command
с аргументами командной строки в args
. Если опустить, args
по умолчанию задает пустой массив.
Третий аргумент используется для указания дополнительных параметров, по умолчанию:
{ cwd: undefined, env: process.env }
Используйте env
, чтобы указать переменные среды, которые будут видимы для нового процесса, по умолчанию это process.env
.
Убедитесь, что вы не вставляете аргументы командной строки в command
, а весь spawn
вызов действителен. Перейдите к следующему шагу.
Шаг 2: Идентифицируйте событие, излучающее событие ошибки
Найдите исходный код для каждого вызова spawn
или child_process.spawn
, т.е.
spawn('some-command', [ '--help' ]);
и прикрепите там прослушиватель событий для события "error", чтобы вы заметили точный Event Emitter, который бросает его как "Unhandled". После отладки этот обработчик можно удалить.
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
(т.е. it undefined
) приведет к тому, что spawn
испустит ошибку ENOENT
, так как не удастся найти какой-либо command
, если только это абсолютный путь к исполняемому файлу.
Когда PATH
установлен правильно, перейдите к следующему шагу. Это должен быть каталог или список каталогов. Последний случай является обычным.
Шаг 4: Убедитесь, что command
существует в каталоге тех, которые определены в PATH
Spawn может испускать ошибку ENOENT
, если имя файла command
(т.е. 'some-command') не существует, по крайней мере, в одном из каталогов, определенных в PATH
.
Найдите точное место command
. В большинстве дистрибутивов Linux это можно сделать с терминала с помощью команды which
. Он укажет вам абсолютный путь к исполняемому файлу (например, выше) или сообщите, не найден ли он.
Пример использования которого и его вывод, когда команда найдена
> which some-command
some-command is /usr/bin/some-command
Пример использования которого и его вывод, когда команда не найдена
> which some-command
bash: type: some-command: not found
прошитые программы являются наиболее распространенной причиной для не найденной команды. Обратитесь к каждой документации команды, если необходимо, и установите ее.
Когда команда представляет собой простой файл script, убедитесь, что он доступен из каталога в PATH
.. Если это не так, переместите его на один или создайте для него ссылку.
После того, как вы определили PATH
правильно установленный и command
доступен из него, вы сможете запустить дочерний процесс без spawn ENOENT
.
Ответ 3
Как @DanielImfeld указал на него, ENOENT будет выброшен, если вы укажете "cwd" в параметрах, но данный каталог не существует.
Ответ 4
Решение для Windows: замените spawn
на node-cross-spawn. Например, например, в начале вашего app.js:
(function() {
var childProcess = require("child_process");
childProcess.spawn = require('cross-spawn');
})();
Ответ 5
Ответ @laconbass помог мне и, вероятно, является наиболее правильным.
Я пришел сюда, потому что я использовал спавн неправильно. В качестве простого примера:
это неверно:
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
});
это потому, что тогда cp.on('exit', fn)
будет всегда cp.on('exit', fn)
, пока bash установлен, в противном случае cp.on('error', fn)
может cp.on('error', fn)
первым, если мы используем его Первый способ, если мы запустим 'npm' напрямую.
Ответ 6
Для ENOENT в Windows 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})
Ответ 7
Для всех, кто может наткнуться на это, если все остальные ответы не помогут, и вы находитесь в Windows, знайте, что в настоящее время существует большая проблема с spawn
в Windows и переменную среды PATHEXT
, которая может привести к тому, что определенные вызовы на запуск не будут работать в зависимости от того, как установлена целевая команда.
Ответ 8
В моем случае я получил эту ошибку, вызванную из-за того, что необходимые зависимые системные ресурсы не были установлены.
В частности, у меня есть приложение NodeJS, которое использует ImageMagick. Несмотря на то, что установлен пакет npm, ядро Linux ImageMagick не было установлено. Я сделал apt-get для установки ImageMagick, и после этого все отлично поработало!
Ответ 9
Я столкнулся с той же проблемой, но нашел простой способ ее исправить.
По-видимому, это ошибки spawn()
, если программа была добавлена в PATH пользователем (например, работают обычные системные команды).
Чтобы исправить это, вы можете использовать модуль 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']);
Ответ 10
Убедитесь, что установленный модуль установлен или полный путь к команде, если он не является модулем node
Ответ 11
Используйте require('child_process').exec
вместо spawn для более конкретного сообщения об ошибке!
например:
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);
});
Ответ 12
Я также проходил через эту досадную проблему, выполняя свои тестовые случаи, поэтому я попробовал много способов решить эту проблему. Но способ для меня - запустить ваш тестовый прогон из каталога, в котором находится ваш основной файл, который включает в себя функцию spawn для nodejs, примерно так:
nodeProcess = spawn('node',params, {cwd: '../../node/', detached: true });
Например, это имя файла test.js, поэтому просто перейдите в папку, в которой он находится. В моем случае это тестовая папка:
cd root/test/
тогда от запуска вашего тестового бегуна в моем случае его мокко, так что это будет так:
mocha test.js
Я потратил больше одного дня, чтобы понять это. Наслаждаться!!
Ответ 13
Я получал эту ошибку при попытке отладки программы node.js из редактора VS Code в системе Debian Linux. Я заметил, что в Windows все работает нормально. Решения, приведенные здесь ранее, не помогли, потому что я не написал никаких команд "икры". Оскорбительный код предположительно был написан Microsoft и скрыт под капотом программы VS Code.
Далее я заметил, что node.js называется node в Windows, но на Debian (и, предположительно, в системах на основе Debian, таких как Ubuntu), он называется nodejs. Поэтому я создал псевдоним - с корневого терминала, я побежал
ln -s/usr/bin/nodejs/usr/local/bin/node
и это решило проблему. Такая же или аналогичная процедура, по-видимому, будет работать в других случаях, когда ваш node.js называется nodejs, но вы запускаете программу, которая ожидает, что она будет называться node, или наоборот.
Ответ 14
У меня такая же ошибка для Windows 8. Проблема в том, что отсутствует переменная среды вашего системного пути. Добавьте значение "C:\Windows\System32 \" в переменную PATH вашей системы.
Ответ 15
Если вы работаете в Windows Node.js делает некоторые смешные дела при обработке котировок, которые могут привести к выдаче команды, которая, как вам известно, работает с консоли, но не выполняется при Node. Например, следующее должно работать:
spawn('ping', ['"8.8.8.8"'], {});
но терпит неудачу. Там есть фантастически недокументированная опция windowsVerbatimArguments
для обработки кавычек/подобных, которые, похоже, делают трюк, просто добавьте следующее к вашему объекту opts:
const opts = {
windowsVerbatimArguments: true
};
и ваша команда должна вернуться в бизнес.
spawn('ping', ['"8.8.8.8"'], { windowsVerbatimArguments: true });
Ответ 16
решение в моем случае
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');
Ответ 17
npm install -g nodemon
помог мне
Ответ 18
Я столкнулся с этой проблемой в Windows, где вызовы exec
и spawn
с одной и той же командой (без аргументов) работали нормально для exec
(поэтому я знал, что моя команда была на $PATH
), но spawn
будет дать ENOENT. Оказалось, что мне просто нужно добавить .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']);
Ответ 19
Вы меняете опцию 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',
}
});
Ответ 20
Если у вас возникла эта проблема с приложением, источник которого вы не можете изменить, подумайте о его вызове с переменной среды NODE_DEBUG
, установленной в child_process
, например, NODE_DEBUG=child_process yarn test
. Это предоставит вам информацию о том, какие командные строки были вызваны в каком каталоге и, как правило, последняя деталь является причиной сбоя.
Ответ 21
Добавьте C:\Windows\System32\
в переменную среды path
.
Действия
-
Перейдите на мой компьютер и свойства
-
Нажмите "Дополнительные настройки"
-
Затем в переменных среды
-
Выберите path
, а затем нажмите на ссылку
-
Вставьте следующие, если они еще не присутствуют: C:\Windows\System32\
-
Закройте командную строку
-
Запустите команду, которую вы хотите запустить
![Windows 8 Environment variables screenshot]()