Как отлаживать "Error: spawn ENOENT"на узле.Яш?

когда я получаю следующую ошибку:

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)

какую процедуру я могу выполнить, чтобы исправить это?

Примечание автора: многие проблемы с этой ошибкой побудили меня опубликовать этот вопрос для будущих ссылок.

вопросы:

  • использование функции spawn с NODE_ENV=production
  • узел.Яш child_process.ошибка ENOENT икры-только под supervisord
  • spawn ENOENT узел.ошибка JS
  • https://stackoverflow.com/questions/27603713/nodejs-spawn-enoent-error-on-travis-calling-global-npm-package
  • node js-child_process spawn ('npm install') в задаче Grunt приводит к ошибке ENOENT
  • запуск" бригадир " задача фатальная ошибка: spawn ENOENT
  • необработанное событие ошибки в узле JS Error: порождение ENOENT в errnoException (child_process.js: 975: 11)
  • узел.js SpookyJS: ошибка при выполнении hello.js
  • https://stackoverflow.com/questions/26572214/run-grunt-on-a-directory-nodewebkit
  • запустите exe-файл с дочерним процессом NodeJS
  • узел: child_process.spawn не работает на Java, даже если он находится в пути (ENOENT)
  • spawn ENOENT ошибка с NodeJS (связанный с PYTHON)
  • изменение размера изображения не работает в узле.js (частично.в JS) (не-установлена зависимость)
  • ошибка установки npm ENOENT (создавать проблемы зависимостей)
  • не удается установить узел.JS-oracle модуль на Windows 7 (создавать проблемы зависимостей)
  • ошибка установки gulp с помощью nodejs в windows (странный случай)

16 ответов


Я нашел особый простой способ получить представление о первопричине:

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 не может найти исполняемый файл для устранения проблемы.


Шаг 1: Обеспечить spawn называется правильно

во-первых, рассмотреть документы для child_process.spawn (command, args, options ):

запускает новый процесс с заданным command, с аргументами командной строки args. Если опустить,args по умолчанию пустой массив.

третий аргумент используется для указания дополнительных параметров, по умолчанию:

{ cwd: undefined, env: process.env }

использовать env чтобы указать переменные среды, которые будут видны новому процессу, значение по умолчанию process.env.

убедитесь, что вы не вводите аргументы командной строки в command и все spawn вызов действителен. Переходите к следующему шагу.

Шаг 2: Определите эмиттер события, который испускает событие ошибки

поиск по исходному коду для каждого вызова spawn или child_process.spawn, т. е.

spawn('some-command', [ '--help' ]);

и прикрепите туда прослушиватель событий для события "ошибка", чтобы вы заметили точный эмиттер событий, который бросает его как "необработанный". После отладки этот обработчик можно удалить.

spawn('some-command', [ '--help' ])
  .on('error', function( err ){ throw err })
;

Execute, и вы должны получить путь к файлу и номер строки, где был зарегистрирован ваш прослушиватель "ошибка". Что-то вроде:

/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 установлен

существует два возможных сценария:

  1. вы полагаетесь на значение по умолчанию spawn поведение, поэтому среда дочернего процесса будет такой же, как process.env.
  2. вы явно передав 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 (то есть это undefined) приведет к spawn для передачи ENOENT, так как невозможно будет найти command если это абсолютный путь к исполняемому файлу.

, когда PATH правильно установлен, перейдите к следующему шагу. это должен быть каталог, или список директорий. Последнее дело обычное.

Шаг 4: Обеспечить command существует в каталоге тех, которые определены в PATH

икра может испускать ENOENT ошибка, если имя файла command (i.e, 'some-command') не существует по крайней мере в одном из каталогов, определенных на PATH.

найдите точное место command. В большинстве дистрибутивов linux это можно сделать с терминала с помощью . Он сообщит вам абсолютный путь к исполняемому файлу (как указано выше) или скажет, если он не найден.

пример использования которого и его вывод, когда команда нашел

> which some-command
some-command is /usr/bin/some-command

пример использования которого и его вывод, когда команда не найдено

> which some-command
bash: type: some-command: not found

miss-installed программы являются наиболее частой причиной для не нашел. при необходимости обратитесь к документации по каждой команде и установите ее.

когда команда представляет собой простой файл сценария, убедитесь, что он доступен из каталога на PATH. если это не так, либо переместить его в одну или сделать ссылку на него.

после определения PATH правильно установлен и command is доступный из него, вы должны иметь возможность порождать свой дочерний процесс без spawn ENOENT быть брошенным.


As @DanielImfeld указал на него, ENOENT будет брошен, если вы укажете " cwd " в параметрах, но данный каталог не существует.


решение для Windows: заменить spawn С node-cross-spawn. Например, как это в начале вашего приложения.js:

(function() {
    var childProcess = require("child_process");
    childProcess.spawn = require('cross-spawn');
})(); 

ответ@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
});

это потому, что тогда cp.on('exit', fn) событие всегда будет срабатывать, пока как bash установлен, в противном случае cp.on('error', fn) событие может сработать первым, если мы используем его первым способом, если мы запускаем " npm " напрямую.


для тех, кто может наткнуться на это, если все остальные ответы не помогут, и вы находитесь в Windows, знайте, что в настоящее время большая проблема с spawn на Windows и PATHEXT переменная окружения, которая может вызвать определенные вызовы spawn не работать в зависимости от того, как установлена целевая команда.


для ENOENT на Windows,https://github.com/nodejs/node-v0.x-archive/issues/2318#issuecomment-249355505 исправьте это.

например, замените spawn ('npm', ['- v'], {stdio:' inherit'}) на:

  • для всех узлов.Яш версия:

    spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['-v'], {stdio: 'inherit'})
    
  • для узла.js 5.X и позже:

    spawn('npm', ['-v'], {stdio: 'inherit', shell: true})
    

в моем случае я получал эту ошибку из-за того, что необходимые зависимые системные ресурсы не были установлены.

более конкретно, у меня есть приложение NodeJS, которое использует ImageMagick. Несмотря на наличие установленного пакета npm, ядро Linux ImageMagick не было установлено. Я сделал apt-get для установки ImageMagick, и после этого все отлично работало!


я столкнулся с той же проблемой, но я нашел простой способ ее исправить. Кажется, это spawn() ошибки, если программа была добавлена в путь пользователем (например, работают обычные системные команды).

чтобы исправить это, вы можете использовать , который модуль (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']);

убедитесь, что модуль для выполнения установлен или полный путь к команде, если это не модуль узла


использовать 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);
});

Я получаю эту ошибку при попытке отладки узла.программа js из редактора кода VS в системе Debian Linux. Я заметил, что то же самое работает нормально на Windows. Решения, ранее приведенные здесь, не очень помогли, потому что я не написал Никаких команд "spawn". Оскорбительный код был предположительно написан Microsoft и спрятан под капотом программы VS Code.

затем я заметил, что узел.js называется узлом в Windows, но на Debian (и, предположительно, на основе Debian такие системы, как Ubuntu) это называется nodejs. Поэтому я создал псевдоним-из корневого терминала, я побежал

ln-s /usr/bin/nodejs /usr/local/bin/node

и это решило проблему. Та же или аналогичная процедура предположительно будет работать в других случаях, когда ваш узел.js называется nodejs, но вы запускаете программу, которая ожидает, что она будет называться node, или наоборот.


Я получил ту же ошибку для Windows 8.Проблема в том, что переменная среды вашего системного пути отсутствует . Добавить "C:\Windows\System32\" значение переменной системного пути.


если вы находитесь на узле Windows.js делает некоторые забавные дела при обработке котировок, которые могут привести к тому, что вы выдадите команду, которая, как вы знаете, работает с консоли, но не работает при запуске в узле. Например, следующее должны работы:

spawn('ping', ['"8.8.8.8"'], {});

но терпит неудачу. Есть фантастически недокументированный вариант windowsVerbatimArguments для обработки котировок/подобных, которые, похоже, делают трюк, просто не забудьте добавить следующее к объекту opts:

const opts = {
    windowsVerbatimArguments: true
};

и ваша команда должен вернуться в бизнес.

 spawn('ping', ['"8.8.8.8"'], { windowsVerbatimArguments: true });

Я также проходил через эту раздражающую проблему во время запуска моих тестовых случаев, поэтому я пробовал много способов ее преодолеть. Но мне все это запустите Test runner из каталога, содержащего ваш основной файл С nodejs наплодил функция что-то вроде этого:

nodeProcess = spawn('node',params, {cwd: '../../node/', detached: true });

например,имя файла-test.js, просто переместить в папку, которая содержит его. В моем случае это тестовая папка вот так:

cd root/test/

затем с запустите тестовый бегун в моем случае его мокко, так что это будет так:

mocha test.js

Я потратил больше одного дня, чтобы понять это. Наслаждайтесь!!


добавить C:\Windows\System32\ до path переменные среды.

шаги

  1. перейти к моей компьютер и свойства

  2. нажать на кнопку Дополнительные параметры

  3. затем на переменные среды

  4. выберите Path а затем нажмите edit

  5. вставьте следующее, если еще нет: C:\Windows\System32\

  6. закройте командную строку

  7. выполните команду, которую вы хотели запустить

Windows 8 Environment variables screenshot