Comment déboguer "Error: spawn ENOENT" sur node.js?

quand 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 la corriger?

note de l'auteur : beaucoup de problèmes avec cette erreur m'ont encouragé à poster cette question pour des références futures.

questions connexes:

226
demandé sur Community 2014-12-29 15:22:00
la source

16 ответов

j'ai trouvé un moyen particulièrement facile d'obtenir l'idée de la cause profonde de:

Error: spawn ENOENT

le problème de cette erreur est qu'il y a vraiment peu d'informations dans le message d'erreur pour vous dire où se trouve le site d'appel, c'est-à-dire quel exécutable/commande n'est pas trouvé, surtout quand vous avez une grande base de code où il y a beaucoup d'appels de spawn. D'un autre côté, si nous connaissons la commande exacte qui cause l'erreur, alors nous pouvons suivre la réponse de @laconbass pour régler le problème.

j'ai trouvé un moyen très facile de repérer quelle commande cause le problème plutôt que d'ajouter des écouteurs d'événements partout dans votre code comme suggéré dans la réponse de @laconbass. L'idée clé est d'envelopper l'appel spawn original avec un wrapper qui imprime les arguments envoyés à l'appel spawn.

Voici la fonction wrapper, mettez-la en haut du index.js ou quelque 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;
})();

la prochaine fois que vous lancerez votre application, avant le message d'exception, vous verrez quelque chose comme ça:

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.

174
répondu Jiaji Zhou 2017-05-23 15:10:54
la source

Étape 1: S'assurer que spawn est appelé de la bonne façon

tout d'abord, passez en revue les docs for child_process.spawn (command, args, options ) :

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

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

{ cwd: undefined, env: process.env }

utiliser env pour spécifier les variables d'environnement qui seront visibles pour le nouveau processus, la valeur par défaut est process.env .

assurez-vous de ne pas mettre d'arguments en ligne de commande dans command et l'appel entier spawn est valide . Passez à l'étape suivante.

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

rechercher sur votre code source pour chaque appel à spawn , ou child_process.spawn , i.e.

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

et y joindre un écouteur d'événement pour l'événement 'error', de sorte que vous vous faites remarquer l'émetteur D'événement exact qui le lance comme 'Unhandled'. Après le débogage, ce gestionnaire peut être retiré.

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 auditeur 'error' était inscrit. 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

faites cette étape encore une fois jusqu'à ce qu'ils ne le soient pas. Vous devez identifier l'auditeur qui émet l'erreur avant de passer à la prochaine étape.

Étape 3: s'assurer que la variable d'environnement $PATH est définie

il y a deux scénarios possibles:

  1. Vous s'appuyer sur le comportement par défaut spawn , de sorte que l'environnement de processus enfant sera le même que process.env .
  2. vous passez explicitement un objet env à spawn sur l'argument options .

dans les deux scénarios, vous devez inspecter la touche PATH sur l'objet environnement que le processus enfant engendré utilisera.

exemple de 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 (i.e., c'est undefined ) fera que spawn émettra l ' "erreur 1519290920 , car il ne sera pas possible de localiser tout command à moins que ce ne soit un chemin absolu vers le fichier exécutable.

quand PATH est correctement défini, procéder à l'étape suivante. Il doit être un répertoire ou une liste de répertoires. Le dernier cas est habituel.

Étape 4: S'assurer que command existe dans un répertoire de ceux définis dans PATH

Spawn peut émettre l' ENOENT d'erreur si le nom de fichier command (j'.e, 'commande') n'existe pas dans au moins l'un des répertoires définis sur PATH .

Localisez l'endroit exact de command . Sur la plupart des distributions linux, cela peut être fait à partir d'un terminal avec la commande which . Il vous indique le chemin absolu vers le fichier exécutable (comme ci-dessus), ou de savoir si il ne l'est pas.

exemple dont l'utilisation et sa sortie quand une commande est trouvé

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

exemple d'utilisation dont et sa sortie quand une commande est introuvable

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

les programmes mal installés sont la cause la plus fréquente d'une commande introuvable . référez-vous à la documentation de chaque commande si nécessaire et installez-la.

lorsque la commande est un simple fichier script, s'assurer qu'il est accessible à partir d'un répertoire sur le PATH . si ce n'est pas le cas, déplacez-le vers l'un d'eux ou faites un lien vers lui.

une fois que vous déterminez que PATH est correctement positionné et que command est accessible à partir de celui-ci, vous devriez être en mesure de lancer votre processus enfant sans spawn ENOENT .

85
répondu laconbass 2017-07-19 18:43:15
la source

comme @DanielImfeld l'a indiqué , ENOENT sera lancé si vous spécifiez" cwd " dans les options, mais le répertoire donné n'existe pas.

23
répondu Leeroy Brun 2017-05-23 15:03:09
la source

Windows solution: remplacer spawn par node-cross-spawn . Par exemple comme ceci au début de votre application.js:

(function() {
    var childProcess = require("child_process");
    childProcess.spawn = require('cross-spawn');
})(); 
21
répondu Nilzor 2016-02-22 22:57:51
la source

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

je suis venu ici parce que j'utilisais spawn incorrectement. Comme exemple simple:

c'est incorrect:

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

c'est incorrect:

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

c'est parce qu'alors l'événement cp.on('exit', fn) va toujours s'allumer, tant que bash est installé, sinon l'événement cp.on('error', fn) pourrait s'allumer en premier, si nous l'utilisons de la première manière, si nous lançons 'npm' directement.

15
répondu Alexander Mills 2018-08-19 09:12:40
la source

pour quiconque pourrait tomber sur cela, si toutes les autres réponses n'aident pas et que vous êtes sur Windows, sachez qu'il y a actuellement un gros problème avec spawn sur Windows et la variable d'environnement PATHEXT qui peut provoquer certains appels à frayer de ne pas fonctionner selon la façon dont la commande cible est installée.

14
répondu Alex Turpin 2015-08-05 22:37:47
la source

pour ENOENT sur Windows, https://github.com/nodejs/node-v0.x-archive/issues/2318#issuecomment-249355505 fixez-le.

p.ex. remplacer spawn ('npm', ['- v'], {stdio: 'inherit'}) par:

  • pour tous les noeuds.version js:

    spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['-v'], {stdio: 'inherit'})
    
  • pour noeud.js 5.x et plus tard:

    spawn('npm', ['-v'], {stdio: 'inherit', shell: true})
    
8
répondu Li Zheng 2016-09-25 05:22:47
la source

dans mon cas, j'ai eu cette erreur due au 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 noyau Linux ImageMagick n'a pas été installé. J'ai fait un apt-get pour installer ImageMagick et après ça tout a bien fonctionné!

6
répondu PromInc 2015-06-12 23:01:19
la source

j'ai rencontré le même problème, mais j'ai trouvé un moyen simple de le résoudre. Il semble qu'il s'agisse d'erreurs spawn() si le programme a été ajouté au chemin par l'utilisateur (par exemple, les commandes système normales fonctionnent).

pour corriger cela, vous pouvez utiliser le qui" module 151970920 "( 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']);
1
répondu Gum Joe 2016-06-26 09:59:35
la source

S'assurer que le module à exécuter est installé ou le chemin complet à commander s'il ne s'agit pas d'un module de noeud

1
répondu Dalton 2016-12-25 23:50:14
la source

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);
});
1
répondu de Raad 2017-06-03 11:51:29
la source

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

ensuite, j'ai remarqué ce nœud.js est appelé node sur Windows mais sur Debian (et probablement sur Systèmes basés sur Debian tels que Ubuntu) il s'appelle nodejs. Donc j'ai créé un alias - à partir d'un terminal root, j'ai lancé

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 noeud.js est appelé nodejs mais vous exécutez un programme qui s'attend à ce qu'il soit appelé node, ou vice-versa.

0
répondu MTGradwell 2016-02-28 03:20:10
la source

j'ai eu la même erreur pour windows 8.Le problème est qu'une variable d'environnement de votre chemin système est manquante . Ajouter "C:\Windows\System32 la valeur\" à votre variable de chemin de système.

0
répondu chayasan 2016-05-06 14:48:08
la source

si vous êtes sur Windows Node.js fait quelques affaires drôles lors de la manipulation des citations qui peuvent vous amener à émettre une commande dont vous savez qu'elle fonctionne à partir de la console, mais qui ne fonctionne pas lorsqu'elle est exécutée dans un noeud. Par exemple, le suivant devrait travailler:

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

mais il échoue. Il y a une option fantastiquement non documentée windowsVerbatimArguments pour gérer les guillemets / similaires qui semble faire l'affaire, assurez-vous juste d'ajouter ce qui suit à votre objet opts:

const opts = {
    windowsVerbatimArguments: true
};

et votre commandement devrait être rétabli.

 spawn('ping', ['"8.8.8.8"'], { windowsVerbatimArguments: true });
0
répondu Joel B 2017-06-18 03:48:34
la source

je traversais aussi ce problème ennuyeux en faisant mes cas de test, donc j'ai essayé de nombreuses façons de le traverser. Mais la façon de fonctionner pour moi est de exécuter votre coureur de test à partir du répertoire qui contient votre fichier principal qui comprend votre nodejs spawn fonction quelque chose comme ceci:

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

par exemple, ce nom de fichier est test.js , donc juste déplacer dans le dossier qui contient . Dans mon cas, c'est un dossier test comme celui-ci:

cd root/test/

puis de exécuter votre coureur d'essai dans mon cas son Moka ainsi il sera comme ceci:

mocha test.js

j'ai perdu plus d'une journée pour le comprendre. Profitez-en!!

0
répondu Rajkumar Bansal 2018-03-13 11:21:53
la source

ajouter C:\Windows\System32\ à la variable d'environnement path .

Étapes

  1. Aller à "mon" 1519110920 de l'ordinateur" et "propriétés de la 1519120920"

  2. Cliquez sur paramètres Avancés

  3. puis sur variables D'environnement

  4. Sélectionnez Path puis cliquez sur " modifier

  5. pâte la suivante si elle n'est pas déjà présente: C:\Windows\System32\

  6. Fermer l'invite de commande

  7. exécutez la commande que vous vouliez exécuter

Windows 8 Environment variables screenshot

-1
répondu vmit dhawan 2016-08-31 23:09:03
la source