nodejs node example child_process child node.js debugging error-handling child-process spawn

node.js - example - spawn process node



¿Cómo depuro "Error: spawn ENOENT" en node.js? (20)

Cuando recibo el siguiente error:

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)

¿Qué procedimiento puedo seguir para solucionarlo?

Nota del autor : Muchos problemas con este error me animaron a publicar esta pregunta para futuras referencias.

Preguntas relacionadas:


¿Estás cambiando la opción env ?

Entonces mira esta respuesta.

Estaba tratando de generar un proceso de nodo y TIL que debería difundir las variables de entorno existentes cuando genera, de lo contrario perderá la PATH entorno PATH y posiblemente otras importantes.

Esta fue la solución para mí:

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'', } });


Paso 1: Asegúrese de que la spawn se llame de la manera correcta

Primero, revise los documentos para child_process.spawn (comando, argumentos, opciones) :

Lanza un nuevo proceso con el command dado, con argumentos de línea de comando en argumentos. Si se omite, el valor predeterminado de args es una matriz vacía.

El tercer argumento se usa para especificar opciones adicionales, que por defecto son:

{ cwd: undefined, env: process.env }

Use env para especificar variables de entorno que serán visibles para el nuevo proceso, el valor predeterminado es process.env .

Asegúrese de no poner ningún argumento de línea de command en el command y toda la llamada de spawn es válida . Proceda al siguiente paso.

Paso 2: identifique el emisor de eventos que emite el evento de error

Busque en su código fuente cada llamada para spawn , o child_process.spawn , es decir

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

y adjunte un detector de eventos para el evento ''error'', para que se dé cuenta del emisor de eventos exacto que lo arroja como ''No controlado''. Después de la depuración, ese controlador puede eliminarse.

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

Ejecute y debería obtener la ruta del archivo y el número de línea donde se registró su escucha de ''error''. Algo como:

/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)

Si las dos primeras líneas siguen siendo

events.js:72 throw er; // Unhandled ''error'' event

repita este paso hasta que no lo estén. Debe identificar al oyente que emite el error antes de continuar con el siguiente paso.

Paso 3: asegúrese de que la variable de entorno $PATH esté establecida

Hay dos escenarios posibles:

  1. Confía en el comportamiento de spawn predeterminado, por lo que el entorno de proceso secundario será el mismo que process.env .
  2. Está explicitando pasar un objeto env para spawn el argumento de options .

En ambos escenarios, debe inspeccionar la clave PATH en el objeto de entorno que utilizará el proceso secundario generado.

Ejemplo para el escenario 1

// inspect the PATH key on process.env console.log( process.env.PATH ); spawn(''some-command'', [''--help'']);

Ejemplo para el escenario 2

var env = getEnvKeyValuePairsSomeHow(); // inspect the PATH key on the env object console.log( env.PATH ); spawn(''some-command'', [''--help''], { env: env });

La ausencia de PATH (es decir, no está undefined ) hará que spawn emita el error ENOENT , ya que no será posible localizar ningún command menos que sea una ruta absoluta al archivo ejecutable.

Cuando la PATH está configurada correctamente, continúe con el siguiente paso. Debe ser un directorio o una lista de directorios. El último caso es el habitual.

Paso 4: Asegúrese de que el command exista en un directorio de los definidos en PATH

Spawn puede emitir el error ENOENT si el command nombre de archivo (es decir, ''algún comando'') no existe en al menos uno de los directorios definidos en PATH .

Localice el lugar exacto de command . En la mayoría de las distribuciones de Linux, esto se puede hacer desde un terminal con el comando which . Le indicará la ruta absoluta al archivo ejecutable (como arriba), o le indicará si no se encuentra.

Ejemplo de uso de cuál y su salida cuando se encuentra un comando

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

Ejemplo de uso de cuál y su salida cuando no se encuentra un comando

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

Los programas mal instalados son la causa más común de un comando no encontrado . Consulte la documentación de cada comando si es necesario e instálelo.

Cuando el comando es un archivo de secuencia de comandos simple, asegúrese de que sea accesible desde un directorio en la PATH . Si no es así, muévalo a uno o haga un enlace a él.

Una vez que determine que PATH está configurado correctamente y que se puede acceder al command desde él, debería poder generar su proceso hijo sin spawn ENOENT .


Agregue C:/Windows/System32/ a la variable de entorno de path .

Pasos

  1. Ir a mi computadora y propiedades

  2. Haga clic en Configuración avanzada

  3. Luego en variables de entorno

  4. Seleccione Path y luego haga clic en editar

  5. Pegue lo siguiente si aún no está presente: C:/Windows/System32/

  6. Cerrar el símbolo del sistema

  7. Ejecute el comando que desea ejecutar


Asegúrese de que el módulo a ejecutar esté instalado o la ruta completa al comando si no es un módulo de nodo



En caso de que tenga este problema con una aplicación cuyo origen no puede modificar, considere invocarlo con la variable de entorno NODE_DEBUG establecida en child_process , por ejemplo, NODE_DEBUG=child_process yarn test . Esto le proporcionará información sobre qué líneas de comando se han invocado en qué directorio y, por lo general, el último detalle es el motivo del error.


En mi caso, recibí este error debido a que no se instalaron los recursos del sistema dependientes necesarios.

Más específicamente, tengo una aplicación NodeJS que está utilizando ImageMagick. A pesar de tener instalado el paquete npm, el núcleo Linux ImageMagick no estaba instalado. Hice un apt-get para instalar ImageMagick y después de eso todo funcionó muy bien.


La respuesta de @ laconbass me ayudó y probablemente sea la más correcta.

Vine aquí porque estaba usando spawn incorrectamente. Como un simple ejemplo:

Esto es incorrecto:

const s = cp.spawn(''npm install -D suman'', [], { cwd: root });

Esto es incorrecto:

const s = cp.spawn(''npm'', [''install -D suman''], { cwd: root });

esto es correcto:

const s = cp.spawn(''npm'', [''install'',''-D'',''suman''], { cwd: root });

Sin embargo, recomiendo hacerlo de esta manera:

const s = cp.spawn(''bash''); s.stdin.end(`cd "${root}" && npm install -D suman`); s.once(''exit'', code => { // exit });

Esto se debe a que el cp.on(''exit'', fn) siempre se activará, siempre que bash esté instalado; de lo contrario, el cp.on(''error'', fn) podría cp.on(''error'', fn) primero, si lo usamos primera forma, si lanzamos ''npm'' directamente.


Me encontré con el mismo problema, pero encontré una manera simple de solucionarlo. Parece ser un error spawn() si el usuario ha agregado el programa a la RUTA (por ejemplo, los comandos normales del sistema funcionan).

Para solucionar esto, puede usar el módulo npm install --save 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'']);


Me encontré con este problema en Windows, donde llamar a exec y spawn con el mismo comando (omitiendo argumentos) funcionó bien para exec (por lo que sabía que mi comando estaba en $PATH ), pero spawn daría ENOENT. Resultó que solo necesitaba agregar .exe al comando que estaba usando:

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'']);


NOTA: Este error casi siempre se debe a que el comando no existe, porque el directorio de trabajo no existe o por un error solo de Windows.

Encontré una manera fácil y particular de tener la idea de la causa raíz de:

Error: spawn ENOENT

El problema de este error es que hay muy poca información en el mensaje de error que le diga dónde está el sitio de la llamada, es decir, qué ejecutable / comando no se encuentra, especialmente cuando tiene una base de código grande donde hay muchas llamadas engendradas . Por otro lado, si conocemos el comando exacto que causa el error, entonces podemos seguir la respuesta de @laconbass para solucionar el problema.

Encontré una manera muy fácil de detectar qué comando causa el problema en lugar de agregar oyentes de eventos en todo el código, como se sugiere en la respuesta de @laconbass. La idea clave es envolver la llamada de generación original con un contenedor que imprime los argumentos enviados a la llamada de generación.

Aquí está la función de contenedor, colóquela en la parte superior de index.js o sea el script de inicio de su servidor.

(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; })();

Luego, la próxima vez que ejecute su aplicación, antes del mensaje de excepción no detectada, verá algo así:

spawn called { ''0'': ''hg'', ''1'': [], ''2'': { cwd: ''/* omitted */'', env: { IP: ''0.0.0.0'' }, args: [] } }

De esta manera, puede saber fácilmente qué comando se ejecuta realmente y luego puede descubrir por qué nodejs no puede encontrar el ejecutable para solucionar el problema.


Obtuve el mismo error para Windows 8. El problema se debe a que falta una variable de entorno de la ruta del sistema. Agregue el valor "C: / Windows / System32 /" a la variable PATH de su sistema.


Para ENOENT en Windows, https://github.com/nodejs/node-v0.x-archive/issues/2318#issuecomment-249355505 corríjalo.

por ejemplo, reemplazar spawn (''npm'', [''-v''], {stdio: ''heredar''}) con:

  • para todas las versiones de node.js:

    spawn(/^win/.test(process.platform) ? ''npm.cmd'' : ''npm'', [''-v''], {stdio: ''inherit''})

  • para node.js 5.xy posterior:

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


Para cualquiera que pueda tropezar con esto, si todas las otras respuestas no ayudan y usted está en Windows, sepa que actualmente hay un gran problema con spawn en Windows y la variable de entorno PATHEXT que puede hacer que ciertas llamadas no funcionen dependiendo sobre cómo se instala el comando de destino.


Recibí este error al intentar depurar un programa node.js desde el editor VS Code en un sistema Debian Linux. Noté que lo mismo funcionaba bien en Windows. Las soluciones dadas anteriormente aquí no fueron de mucha ayuda porque no había escrito ningún comando "spawn". El código ofensivo fue presumiblemente escrito por Microsoft y oculto bajo el capó del programa VS Code.

Luego noté que node.js se llama nodo en Windows pero en Debian (y presumiblemente en sistemas basados ​​en Debian como Ubuntu) se llama nodejs. Así que creé un alias: desde un terminal raíz, ejecuté

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

Y esto resolvió el problema. El mismo procedimiento o uno similar probablemente funcionará en otros casos en los que su node.js se llama nodejs pero está ejecutando un programa que espera que se llame nodo, o viceversa.


Si está en Windows Node.js hace algunos negocios divertidos cuando maneja citas que pueden resultar en que emita un comando que sabe que funciona desde la consola, pero no cuando se ejecuta en Node. Por ejemplo, lo siguiente debería funcionar:

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

pero falla Hay una opción fantásticamente indocumentada windowsVerbatimArguments para manejar citas / similares que parece ser el truco, solo asegúrese de agregar lo siguiente a su objeto de opciones:

cd root/test/

y tu comando debería estar de vuelta en el negocio.

mocha test.js


Solución de Windows: Reemplace spawn con node-cross-spawn . Por ejemplo, así al principio de tu app.js:

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


También estaba pasando por este molesto problema mientras ejecutaba mis casos de prueba, así que intenté muchas formas de superarlo. Pero la forma en que funciona para mí es ejecutar su corredor de prueba desde el directorio que contiene su archivo principal que incluye su función de generación de nodejs algo como esto:

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

Por ejemplo, este nombre de archivo es test.js , así que simplemente muévase a la carpeta que lo contiene . En mi caso, es una carpeta de prueba como esta:

const opts = { windowsVerbatimArguments: true };

luego, de ejecutar su corredor de prueba en mi caso, es moca, por lo que será así:

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

He perdido más de un día para resolverlo. ¡¡Disfrutar!!


Utilice require(''child_process'').exec lugar de spawn para obtener un mensaje de error más específico.

por ejemplo:

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); });


solución en mi caso

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'');