Comment déboguer “Erreur: spawn ENOENT” sur node.js?

Lorsque j’obtiens l’erreur suivante:

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) 

Quelle procédure puis-je suivre pour y remédier?

Note de l’auteur : Beaucoup de problèmes avec cette erreur m’ont incité à poster cette question pour de futures références.

Questions connexes:

  • en utilisant la fonction spawn avec NODE_ENV = production
  • erreur node.js child_process.spawn ENOENT – seulement sous supervisor
  • générer une erreur ENOENT node.js
  • https://stackoverflow.com/questions/27603713/nodejs-spawn-enoent-error-on-travis-calling-global-npm-package
  • Le noeud JS – child_process spawn (‘npm install’) dans la tâche Grunt génère une erreur ENOENT
  • Exécution de la tâche “contremaître” Erreur fatale: spawn ENOENT
  • événement d’erreur non géré dans le noeud js Erreur: spawn ENOENT à errnoException (child_process.js: 975: 11)
  • Node.js SpookyJS: erreur lors de l’exécution de hello.js
  • https://stackoverflow.com/questions/26572214/run-grunt-on-a-directory-nodewebkit
  • Exécuter le fichier exe avec NodeJS Child Process
  • Node: child_process.spawn ne fonctionne pas sur Java même s’il se trouve dans le chemin (ENOENT)
  • spawn erreur ENOENT avec NodeJS (lié PYTHON)
  • le redimensionnement de l’image ne fonctionne pas dans node.js (partial.js) (dépendance non installée)
  • Erreur d’installation npm ENOENT (problème de dépendance de génération)
  • Impossible d’installer node.js – module Oracle sur Windows 7 (problème de dépendance de génération)
  • Erreur lors de l’installation de gulp en utilisant nodejs sur windows (cas étrange)

J’ai trouvé un moyen simple d’obtenir l’idée de la cause fondamentale de:

 Error: spawn ENOENT 

Le problème de cette erreur est que le message d’erreur contient très peu d’informations pour vous dire où se trouve le site d’appel, c’est-à-dire quel exécutable / commande n’a pas été trouvé, surtout lorsque . D’autre part, si nous connaissons la commande exacte à l’origine de l’erreur, nous pouvons suivre la réponse de @laconbass pour résoudre le problème.

J’ai trouvé un moyen très simple de repérer la commande qui pose problème plutôt que d’append des écouteurs d’événement partout dans votre code, comme le suggère la réponse de @laconbass. L’idée principale consiste à envelopper l’appel d’origine avec un wrapper qui imprime les arguments envoyés à l’appel spawn.

Voici la fonction wrapper, placez-la en haut de l’ index.js ou quel que soit le script de démarrage de votre serveur.

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

Ensuite, la prochaine fois que vous exécuterez votre application, avant le message d’exception non capturée, vous verrez quelque chose comme ceci:

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

De cette façon, vous pouvez facilement savoir quelle commande est réellement exécutée et ensuite vous pouvez découvrir pourquoi nodejs ne peut pas trouver l’exécutable pour résoudre le problème.

Étape 1: Assurez-vous que le spawn est appelé de la bonne façon

Commencez par examiner les documents relatifs à child_process.spawn (commande, args, options) :

Lance un nouveau processus avec la command donnée, avec des arguments de ligne de commande dans args . Si omis, args est par défaut un tableau vide.

Le troisième argument est utilisé pour spécifier des options supplémentaires, par défaut:

{ cwd: undefined, env: process.env }

Utilisez env pour spécifier les variables d’environnement qui seront visibles pour le nouveau processus, par défaut process.env .

Assurez-vous de ne pas mettre d’arguments en ligne de command et que la totalité de l’appel est valide . Passez à l’étape suivante.

Étape 2: Identifier l’émetteur d’événement qui émet l’événement d’erreur

Recherchez sur votre code source chaque appel à spawn ou child_process.spawn , c.-à-d.

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

et attachez-y un écouteur d’événement pour l’événement ‘error’, ainsi vous remarquerez l’émetteur d’événement exact qui le lance en tant que ‘Unhandled’. Après le débogage, ce gestionnaire peut être supprimé.

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

Exécutez et vous devriez obtenir le chemin du fichier et le numéro de ligne où votre écouteur «erreur» a été enregistré. Quelque chose comme:

 /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 les deux premières lignes sont toujours

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

recommencez cette étape jusqu’à ce qu’ils ne le soient plus. Vous devez identifier l’auditeur qui émet l’erreur avant de passer à l’étape suivante.

Étape 3: Assurez-vous que la variable d’environnement $PATH est définie

Il existe deux scénarios possibles:

  1. Vous comptez sur le comportement de spawn par défaut, donc l’environnement de processus enfant sera identique à process.env .
  2. Vous passez explicitement un object env pour spawn sur l’argument options .

Dans les deux scénarios, vous devez inspecter la clé PATH sur l’object d’environnement utilisé par le processus enfant généré.

Exemple pour le scénario 1

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

Exemple pour le scénario 2

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

L’absence de PATH (c’est-à-dire undefined ) provoquera l’ ENOENT erreur ENOENT , car il ne sera possible de localiser aucune command moins qu’il ne s’agisse d’un chemin absolu vers le fichier exécutable.

Lorsque PATH est correctement défini, passez à l’étape suivante. Ce devrait être un répertoire ou une liste de répertoires. Le dernier cas est l’habituel.

Étape 4: Assurez-vous que la command existe dans un répertoire de ceux définis dans PATH

Spawn peut émettre l’erreur ENOENT si la command filename (c’est-à-dire «some-command») n’existe pas dans au moins un des répertoires définis sur PATH .

Localisez le lieu exact de command . Sur la plupart des dissortingbutions Linux, cela peut être fait à partir d’un terminal avec la commande which . Il vous indiquera le chemin absolu du fichier exécutable (comme ci-dessus), ou indiquera s’il n’est pas trouvé.

Exemple d’utilisation dont et sa sortie lorsqu’une commande est trouvée

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

Exemple d’utilisation dont et sa sortie lorsqu’une commande est introuvable

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

les programmes mal installés sont la cause la plus courante d’une commande non trouvée . Reportez-vous à chaque documentation de commande si nécessaire et installez-la.

Lorsque command est un simple fichier script, assurez-vous qu’il est accessible depuis un répertoire du PATH . Si ce n’est pas le cas, déplacez-le vers un autre ou créez un lien vers celui-ci.

Une fois que vous avez déterminé que PATH est correctement défini et que la command est accessible à partir de celui-ci, vous devriez être capable de générer votre processus enfant sans que spawn ENOENT soit lancé.

Comme @DanielImfeld l’a indiqué , ENOENT sera lancé si vous spécifiez “cwd” dans les options, mais le répertoire donné n’existe pas.

Solution Windows: remplacez spawn par node-cross-spawn . Par exemple, comme ceci au début de votre app.js:

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

Pour tous ceux qui pourraient tomber sur cela, si toutes les autres réponses ne vous aident pas et que vous êtes sous Windows, sachez qu’il ya actuellement un gros problème avec spawn sous Windows et la variable d’environnement PATHEXT qui peut causer certains appels à ne pas fonctionner selon sur la façon dont la commande cible est installée.

La réponse de @ laconbass m’a aidé et est probablement la plus correcte.

Je suis venu ici parce que je n’utilisais pas correctement Spawn. Comme exemple simple:

Ceci est une erreur:

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

Ceci est une erreur:

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

c’est correct:

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

Cependant, je recommande de le faire de cette façon:

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

En effet, l’ cp.on('exit', fn) se déclenche toujours, tant que bash est installé, sinon l’ cp.on('error', fn) risque de se déclencher en premier, si nous l’utilisons Premièrement, si nous lançons directement «npm».

Pour ENOENT on Windows, https://github.com/nodejs/node-v0.x-archive/issues/2318#issuecomment-249355505 le réparer.

par exemple remplacer spawn (‘npm’, [‘-v’], {stdio: ‘inherit’}) avec:

  • pour toute version de node.js:

     spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['-v'], {stdio: 'inherit'}) 
  • pour node.js 5.x et versions ultérieures:

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

Dans mon cas, cette erreur a été provoquée par le fait que les ressources système dépendantes nécessaires n’étaient pas installées.

Plus précisément, j’ai une application NodeJS qui utilise ImageMagick. Malgré l’installation du paquet npm, le kernel Linux ImageMagick n’a pas été installé. J’ai fait un apt-get pour installer ImageMagick et ensuite tout a bien fonctionné!

J’ai rencontré le même problème, mais j’ai trouvé un moyen simple de le résoudre. Il semble y avoir des erreurs spawn() si le programme a été ajouté au PATH par l’utilisateur (par exemple, les commandes normales du système fonctionnent).

Pour résoudre ce problème, vous pouvez utiliser le module ( 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']); 

S’assurer que le module à exécuter est installé ou que le chemin d’access complet à la commande est différent de celui d’un module de noeud

Utilisez require('child_process').exec au lieu de spawn pour un message d’erreur plus spécifique!

par exemple:

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

J’avais cette erreur en essayant de déboguer un programme node.js de l’éditeur VS Code sur un système Debian Linux. J’ai remarqué la même chose fonctionnait bien sur Windows. Les solutions précédemment données ici n’ont pas été d’une grande aide car je n’avais pas écrit de commandes “spawn”. Le code incriminé a probablement été écrit par Microsoft et caché sous le capot du programme VS Code.

Ensuite, j’ai remarqué que node.js est appelé node sous Windows, mais sur Debian (et probablement sur les systèmes basés sur Debian tels que Ubuntu), il s’appelle nodejs. J’ai donc créé un alias – à partir d’un terminal racine, j’ai couru

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

et cela a résolu le problème. La même procédure ou une procédure similaire fonctionnera probablement dans d’autres cas où votre node.js s’appelle nodejs, mais vous exécutez un programme qui s’attend à ce qu’il soit appelé noeud, ou vice-versa.

J’ai la même erreur pour Windows 8. Le problème est dû au fait qu’une variable d’environnement de votre chemin système est manquante. Ajoutez la valeur “C: \ Windows \ System32 \” à votre variable système PATH.

Si vous êtes sous Windows, Node.js fait des choses amusantes lors du traitement des devis qui peuvent vous amener à émettre une commande qui fonctionne à partir de la console, mais pas lorsqu’elle est exécutée dans Node. Par exemple, les éléments suivants devraient fonctionner:

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

mais échoue. Il existe une option windowsVerbatimArguments non documentée, windowsVerbatimArguments pour gérer les guillemets / similaires qui semble faire l’affaire, mais assurez-vous simplement d’append ce qui suit à votre object opts:

 const opts = { windowsVerbatimArguments: true }; 

et votre commande devrait être de retour dans les affaires.

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

J’étais également confronté à ce problème ennuyeux lors de l’exécution de mes scénarios de test, alors j’ai essayé de nombreuses façons de le faire. Mais le moyen fonctionne pour moi est d’ exécuter votre programme de test à partir du répertoire qui contient votre fichier principal qui inclut votre fonction spawn nodejs quelque chose comme ceci:

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

Par exemple, ce nom de fichier est test.js , déplacez-vous simplement vers le dossier qui le contient . Dans mon cas, c’est un dossier de test comme celui-ci:

 cd root/test/ 

alors de courir votre coureur de test dans mon cas c’est son moka donc ce sera comme ça:

 mocha test.js 

J’ai perdu plus d’une journée pour comprendre. Prendre plaisir!!

Ajoutez C:\Windows\System32\ à la variable d’environnement de path .

Pas

  1. Aller sur mon ordinateur et mes propriétés

  2. Cliquez sur Paramètres avancés

  3. Puis sur les variables d’environnement

  4. Sélectionnez Path puis cliquez sur edit

  5. Collez les éléments suivants s’ils ne sont pas déjà présents: C:\Windows\System32\

  6. Fermer l’invite de commande

  7. Exécutez la commande que vous souhaitez exécuter

Capture d'écran des variables d'environnement Windows 8