IT-Swarm.Net

میں نوڈ. جے ایس پر "خرابی: اسپون 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)

میں اسے ٹھیک کرنے کے لئے کس طریقہ کار پر عمل کرسکتا ہوں؟

مصنف نوٹ : اس خامی کے بہت سارے معاملات نے مجھے یہ سوال مستقبل کے حوالہ جات کے ل post پوسٹ کرنے کی ترغیب دی۔.

متعلقہ سوالات:

281
laconbass

میں نے اس کی بنیادی وجہ کا اندازہ لگانے کا ایک خاص آسان طریقہ تلاش کیا۔

Error: spawn ENOENT

اس غلطی کا مسئلہ یہ ہے کہ ، غلطی کے پیغام میں واقعی بہت کم معلومات موجود ہیں جو آپ کو یہ بتانے کے لئے کہ کال سائٹ کہاں ہے ، یعنی کون سا عمل درآمد/کمانڈ نہیں ملتا ہے ، خاص طور پر جب آپ کے پاس ایک بہت بڑا کوڈ بیس ہوتا ہے جہاں بہت زیادہ اسپن کالز ہوتی ہیں۔ . دوسری طرف ، اگر ہم غلطی کا سبب بننے والے عین کمانڈ کو جانتے ہیں تو ہم مسئلہ کو ٹھیک کرنے کے لئے @ laconbass 'جواب پر عمل کرسکتے ہیں۔.

مجھے یہ معلوم کرنے کا ایک بہت آسان طریقہ ملا ہے کہ کون سا کمانڈ اس مسئلے کا سبب بننے کی بجائے اپنے کوڈ میں ہر جگہ واقعہ سننے والوں کو شامل کرنے کے بجائےlaconbass کے جواب میں تجویز کیا گیا ہے۔ کلیدی خیال یہ ہے کہ اصلی سپون کال کو ریپر سے لپیٹنا ہے جو سپون کال پر بھیجے جانے والے دلائل پرنٹ کرتا ہے۔.

یہاں ریپر فنکشن ہے ، اسے 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: [] } }

اس طرح آپ آسانی سے جان سکتے ہیں کہ اصل میں کون سا کمانڈ عمل میں لایا جاتا ہے اور پھر آپ یہ معلوم کرسکتے ہیں کہ نوڈج مسئلے کو ٹھیک کرنے کے لئے کیوں عملدرآمد نہیں پاسکتے ہیں۔.

196
Jiaji Zhou

پہلا مرحلہ: یقینی بنائیں spawn کو صحیح راستہ کہا جاتا ہے۔

پہلے ، چائلڈ_پروسیس ڈاٹ دستاویز کے دستاویزات (کمانڈ ، آرگس ، آپشنز)) کا جائزہ لیں :

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

عملدرآمد کریں اور آپ کو فائل کا راستہ اور لائن نمبر ملنا چاہئے جہاں آپ کا 'غلطی' سننے والا اندراج ہوا تھا۔ کی طرح کچھ:

/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 (یعنی 'کچھ کمانڈ') PATH پر متعین کم از کم ایک ڈائریکٹری میں موجود نہیں ہے۔

command کی عین جگہ معلوم کریں۔ زیادہ تر لینکس کی تقسیم پر ، یہ which کمانڈ والے ٹرمینل سے کیا جاسکتا ہے۔ یہ آپ کو پھانسی دینے والی فائل (جیسے جیسے اوپر) کا مطلق راستہ بتائے گی ، یا بتائے گی کہ یہ نہیں ملی ہے۔.

جب کمانڈ ملا = جب # اور + اس کے استعمال کی مثال

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

جب کمانڈ نہیں ملا تو - اور/اس کے آؤٹ پٹ کے استعمال کی مثال

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

مس انسٹال کردہ پروگرام ایک نہیں ملا کمانڈ کی سب سے عام وجہ ہیں۔ اگر ضرورت ہو تو ہر کمانڈ دستاویزات کا حوالہ دیں اور اسے انسٹال کریں۔.

جب کمانڈ ایک سادہ اسکرپٹ فائل ہوتی ہے تو اس بات کو یقینی بناتی ہے کہ وہ PATH پر موجود ڈائریکٹری سے قابل رسائی ہے۔ اگر ایسا نہیں ہے تو ، اسے ایک میں منتقل کریں یا اس سے لنک بنائیں۔.

ایک بار جب آپ یہ طے کرلیں کہ PATH درست طریقے سے ترتیب دی گئی ہے اور command اس سے قابل رسائی ہے تو ، آپ کو spawn ENOENT پھینک دیئے بغیر اپنے بچے کے عمل کو بڑھاوا دینے کے قابل ہونا چاہئے۔.

100
laconbass

جیسے @ ڈینیئل ایمفیلڈ نے اس کی نشاندہی کی ، اگر آپ اختیارات میں "cwd" متعین کرتے ہیں تو ENOENT پھینک دیا جائے گا ، لیکن دی گئی ڈائریکٹری موجود نہیں ہے۔.

29
Leeroy Brun

ونڈوز حل: spawn کو نوڈ کراس اسپون سے تبدیل کریں۔ مثال کے طور پر اپنی ایپ کے آغاز میں اس طرح: جے ایس:

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

@ لاکونباس کے جواب نے میری مدد کی اور شاید زیادہ درست ہے۔.

میں یہاں آیا ہوں کیونکہ میں اسپون کو غلط طریقے سے استعمال کر رہا تھا۔ ایک سادہ مثال کے طور پر:

یہ غلط ہے:

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) ایونٹ ہمیشہ ہی فائر ہوتا رہے گا ، جب تک کہ انش انسٹال ہوجائے ، بصورت دیگر ، cp.on('error', fn) ایونٹ سب سے پہلے فائر ہوسکتا ہے ، اگر ہم اسے پہلی بار استعمال کرتے ہیں ، اگر ہم براہ راست 'npm' لانچ کرتے ہیں۔.

22
Alexander Mills

جو بھی اس سے ٹھوکر کھا سکتا ہے ، اگر دوسرے تمام جوابات مدد نہیں کرتے اور آپ ونڈوز پر ہیں تو ، جان لیں کہ اس وقت موجود ہے ونڈوز پر spawn کا ایک بڑا مسئلہ اور PATHEXT ماحول متغیر جو یقینی بن سکتا ہے سپان سے مطالبہ کرتا ہے کہ ٹارگٹ کمانڈ کیسے انسٹال ہوا ہے اس پر منحصر ہے کام نہیں کریں گے۔.

16
Alex Turpin

ونڈوز پر ENOENT کے لئے ، https://github.com/nodejs/node-v0.x-archive/issues/2318#issuecomment-249355505 اسے درست کریں۔.

جیسے اسپون ('npm'، ['-v'] '، {stdio:' विरासत '}) کو اس کے ساتھ تبدیل کریں:

  • تمام نوڈ ڈاٹ جے ایس ورژن کیلئے:

    spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['-v'], {stdio: 'inherit'})
    
  • نوڈ. جے ایس کے لئے 5.x اور بعد میں:

    spawn('npm', ['-v'], {stdio: 'inherit', Shell: true})
    
16
Li Zheng

میرے معاملے میں ، ضروری انحصار کرنے والے نظام کے وسائل کی تنصیب نہ ہونے کی وجہ سے میں یہ غلطی پھینک رہا تھا۔.

خاص طور پر ، میرے پاس نوڈ جے ایس ایپ ہے جو امیج میجک کو استعمال کررہی ہے۔ این پی ایم پیکج انسٹال ہونے کے باوجود ، بنیادی لینکس امیج میگ انسٹال نہیں ہوا تھا۔ میں نے امیج میجک انسٹال کرنے کے لئے ایک قابل عمل کام کیا اور اس کے بعد سب نے بہت اچھا کام کیا!

6
PromInc

میں اسی پریشانی میں مبتلا ہوگیا ، لیکن مجھے اس کو ٹھیک کرنے کا ایک آسان سا طریقہ مل گیا۔ اگر یہ صارف PATH میں صارف کے ذریعہ شامل کیا گیا ہو تو (مثال کے طور پر نارمل سسٹم کے کمانڈ کام کرتا ہے) spawn() کی خرابیاں معلوم ہوتا ہے۔.

اس کو درست کرنے کے ل you ، آپ جو ماڈیول (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']);
2
Gum Joe

یقینی بنائیں کہ عمل درآمد کے لئے ماڈیول انسٹال ہے یا اگر یہ نوڈ ماڈیول نہیں ہے تو کمانڈ کا پورا راستہ ہے۔

1
Dalton

میں اپنے آزمائشی مقدمات چلاتے ہوئے بھی اس پریشان کن پریشانی سے گزر رہا تھا ، لہذا میں نے اس سے نمٹنے کے لئے بہت سے طریقوں کی کوشش کی۔ لیکن میرے لئے کام کرنے کا طریقہ یہ ہے اپنے ٹیسٹ رنر کو ڈائرکٹری سے چلائیں جس میں آپ کی فائل شامل ہو جس میں آپ کا نوڈج سپون اس طرح کام کرنا ہے:

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

مثال کے طور پر ، یہ فائل کا نام test.js ہے ، لہذا صرف اس فولڈر میں منتقل کریں جس میں یہ موجود ہے۔ میرے معاملے میں ، یہ ٹیسٹ فولڈر اس طرح ہے:

cd root/test/

پھر سے اپنے ٹیسٹ رنر کو چلائیں میرے معاملے میں اس کا موچھا اس طرح ہوگا:

mocha test.js

اس کا پتہ لگانے کے لئے میں نے ایک دن سے زیادہ ضائع کیا ہے۔ لطف اٹھائیں !!

0
Rajkumar Bansal

مزید مخصوص غلطی والے پیغام کے لئے اسپون کے بجائے require('child_process').exec استعمال کریں!

مثال کے طور پر:

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);
});
0
de Raad

میرے معاملے میں حل

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');
0
Dan Alboteanu

اگر آپ ونڈوز نوڈ ڈاٹ جے ایس پر ہیں تو قیمتیں سنبھالنے کے وقت کچھ مضحکہ خیز کاروبار کرتے ہیں جس کے نتیجے میں آپ کو کمانڈ جاری کرنے کا نتیجہ مل سکتا ہے جس کے بارے میں آپ جانتے ہو کہ کنسول سے کام کرتا ہے ، لیکن نوڈ میں چلتے وقت ایسا نہیں ہوتا ہے۔ مثال کے طور پر مندرجہ ذیل چاہئے کام:

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

لیکن ناکام ہوجاتا ہے۔ لگتا ہے کہ حوالوں کو سنبھالنے کے لئے ایک بہت ہی غیر منقولہ آپشن windowsVerbatimArguments ہے/ایسا ہی لگتا ہے جس سے یہ چال چلی آرہی ہے ، صرف آپ کے اوپٹ اعتراض میں درج ذیل کو شامل کرنے کی بات کا یقین کریں:

const opts = {
    windowsVerbatimArguments: true
};

اور آپ کا حکم واپس کاروبار میں ہونا چاہئے۔.

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

میں نے ونڈوز پر اس مسئلے کا سامنا کرنا پڑا ، جہاں exec اور spawn پر عین اسی کمانڈ (دلائل کو چھوڑ کر) کے ساتھ exec کے لئے ٹھیک کام کیا گیا تھا (لہذا میں جانتا تھا کہ میرا حکم جاری ہے $PATH) ، لیکن spawn ENOENT دے گی۔ معلوم ہوا کہ مجھے صرف اس کمانڈ میں .exe شامل کرنے کی ضرورت ہے جس کا میں استعمال کر رہا تھا:

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

ونڈوز 8 میں بھی مجھے اسی طرح کی خرابی ہوئی ہے۔ مسئلہ اس وجہ سے ہے کہ آپ کے سسٹم کے راستے میں سے ایک ماحولیاتی متغیر غائب ہے۔ اپنے نظام PATH متغیر میں "C:\Windows\System32." کی قدر شامل کریں۔.

0
chayasan

مجھے یہ غلطی اس وقت ہو رہی تھی جب ڈیبین لینکس سسٹم پر وی ایس کوڈ ایڈیٹر کے اندر سے نوڈ. جے ایس پروگرام ڈیبگ کرنے کی کوشش کی جارہی تھی۔ میں نے دیکھا کہ ونڈوز میں بھی اسی چیز نے ٹھیک کام کیا۔ پہلے یہاں دیئے گئے حل زیادہ مددگار نہیں تھے کیونکہ میں نے کوئی "سپان" کمانڈ نہیں لکھا تھا۔ گستاخانہ کوڈ غالبا Microsoft مائیکرو سافٹ نے لکھا تھا اور VS کوڈ پروگرام کے تحت چھپا ہوا تھا۔.

آگے میں نے دیکھا کہ نوڈ. جے کو ونڈوز پر نوڈ کہا جاتا ہے لیکن ڈیبیئن (اور غالبا De اوبیٹو جیسے ڈیبین پر مبنی نظام پر) اسے نوڈج کہتے ہیں۔ تو میں نے ایک عرف پیدا کیا - جڑ کے ٹرمینل سے ، میں بھاگ گیا۔

ln -s/usr/bin/nodejs/usr/مقامی/بن/نوڈ۔

اور اس سے مسئلہ حل ہوگیا۔ ایک ہی یا اسی طرح کا طریقہ کار شاید دوسرے معاملات میں بھی کام کرے گا جہاں آپ کے نوڈ ڈس جے کو نوڈج کہا جاتا ہے لیکن آپ ایک ایسا پروگرام چلا رہے ہیں جس کی توقع ہے کہ اس کو نوڈ کہا جائے گا۔.

0
MTGradwell