Как отладить "Ошибка: вызвать 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