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:
- usando la función spawn con NODE_ENV = producción
- node.js child_process.spawn Error ENOENT - solo bajo supervisión
- spawn ENOENT error node.js
- https://stackoverflow.com/questions/27603713/nodejs-spawn-enoent-error-on-travis-calling-global-npm-package
- Nodo JS: la generación de proceso hijo (''npm install'') en la tarea Grunt produce un error ENOENT
- Ejecutando tarea "capataz" Error fatal: engendrar ENOENT
- evento de error no controlado en el nodo js Error: genera ENOENT en errnoException (child_process.js: 975: 11)
- Node.js SpookyJS: error al ejecutar hello.js
- https://stackoverflow.com/questions/26572214/run-grunt-on-a-directory-nodewebkit
- Ejecute el archivo exe con Child Process NodeJS
- Nodo: child_process.spawn no funciona en Java aunque esté en la ruta (ENOENT)
- generar ENOENT error con NodeJS (relacionado con PYTHON)
- el cambio de tamaño de la imagen no funciona en node.js (partial.js) (dependencia no instalada)
- npm error de instalación ENOENT (problema de dependencia de compilación)
- No se puede instalar node.js - módulo oracle en Windows 7 (problema de dependencia de compilación)
- Error al instalar Gulp usando nodejs en Windows (caso extraño)
¿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 deargs
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 esprocess.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:
-
Confía en el comportamiento de
spawn
predeterminado, por lo que el entorno de proceso secundario será el mismo queprocess.env
. -
Está explicitando pasar un objeto
env
paraspawn
el argumento deoptions
.
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
-
Ir a mi computadora y propiedades
-
Haga clic en Configuración avanzada
-
Luego en variables de entorno
-
Seleccione
Path
y luego haga clic en editar -
Pegue lo siguiente si aún no está presente:
C:/Windows/System32/
-
Cerrar el símbolo del sistema
-
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
Como lo señaló @DanielImfeld , ENOENT se generará si especifica "cwd" en las opciones, pero el directorio dado no existe.
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'');