node.js শেল কমান্ড প্রয়োগ


113

আমি এখনও কীভাবে লিনাক্স বা উইন্ডোজ শেল কমান্ড চালাতে পারি এবং নোড.জেএস এর মধ্যে আউটপুট ক্যাপচার করতে পারি তার সূক্ষ্ম পয়েন্টগুলি উপলব্ধি করার চেষ্টা করছি; শেষ পর্যন্ত, আমি এই জাতীয় কিছু করতে চাই ...

//pseudocode
output = run_command(cmd, args)

গুরুত্বপূর্ণ অংশটি হ'ল outputঅবশ্যই বিশ্বব্যাপী স্কোপযুক্ত ভেরিয়েবল (বা বস্তু) এর জন্য উপলব্ধ। আমি নীচের ফাংশনটি চেষ্টা করেছিলাম, তবে কোনও কারণে, আমি undefinedকনসোলে মুদ্রিত হয়েছি ...

function run_cmd(cmd, args, cb) {
  var spawn = require('child_process').spawn
  var child = spawn(cmd, args);
  var me = this;
  child.stdout.on('data', function(me, data) {
    cb(me, data);
  });
}
foo = new run_cmd('dir', ['/B'], function (me, data){me.stdout=data;});
console.log(foo.stdout);  // yields "undefined" <------

কোডটি উপরে যেখানে ব্রেক করা হয়েছে তা বুঝতে আমার সমস্যা হচ্ছে ... সেই মডেলের খুব সাধারণ প্রোটোটাইপ কাজ করে ...

function try_this(cmd, cb) {
  var me = this;
  cb(me, cmd)
}
bar = new try_this('guacamole', function (me, cmd){me.output=cmd;})
console.log(bar.output); // yields "guacamole" <----

কেউ আমাকে বুঝতে সাহায্য করে যে try_this()কাজ করে কেন , এবং run_cmd()না? এফডাব্লুআইডাব্লু, আমার ব্যবহার করা দরকার child_process.spawn, কারণ child_process.exec200 কেবি বাফার সীমা রয়েছে।

চূড়ান্ত রেজোলিউশন

আমি জেমস হোয়াইটের উত্তর গ্রহণ করছি, তবে এটি হ'ল কোড যা আমার পক্ষে কাজ করেছে ...

function cmd_exec(cmd, args, cb_stdout, cb_end) {
  var spawn = require('child_process').spawn,
    child = spawn(cmd, args),
    me = this;
  me.exit = 0;  // Send a cb to set 1 when cmd exits
  me.stdout = "";
  child.stdout.on('data', function (data) { cb_stdout(me, data) });
  child.stdout.on('end', function () { cb_end(me) });
}
foo = new cmd_exec('netstat', ['-rn'], 
  function (me, data) {me.stdout += data.toString();},
  function (me) {me.exit = 1;}
);
function log_console() {
  console.log(foo.stdout);
}
setTimeout(
  // wait 0.25 seconds and print the output
  log_console,
250);

2
ফাইনাল রেজোলিউশনের আপনাকে সেট করা উচিত me.stdout = "";মধ্যে cmd_exec()concatenating প্রতিরোধ undefinedফলাফলের শুরুতে।
অওরসিক

আরে, এই চূড়ান্ত রেজোলিউশন কোডটি সম্পূর্ণ ভয়াবহ, আপনার নেটস্যাট চালাতে যদি 0.25 সেকেন্ডের বেশি সময় লাগে?
স্টিভেন লু

উম্ম্ম্ম ... সম্ভবত যে কোনও উত্তর আমি বোনাস দিয়েছি তা ব্যবহার করুন ?????
মাইক পেনিংটন

উত্তর:


89

এখানে তিনটি সমস্যা সমাধান করা দরকার:

প্রথমটি হ'ল stdout asynchronously ব্যবহার করার সময় আপনি সিঙ্ক্রোনাস আচরণের প্রত্যাশা করছেন। আপনার run_cmdফাংশনের সমস্ত কলগুলি অবিচ্ছিন্ন, সুতরাং এটি শিশু প্রক্রিয়াটিকে উত্সাহিত করবে এবং কিছু, সমস্ত, বা ডেটাগুলির কোনওটি স্ট্যাডআউট ছাড়াই পড়া হয়নি তা নির্বিশেষে তাৎক্ষণিকভাবে ফিরে আসবে। যেমন আপনি যখন দৌড়াবেন

console.log(foo.stdout);

এই মুহুর্তে foo.stdout সংরক্ষণের জন্য যা কিছু ঘটবে আপনি তা পান এবং এটির কোনও গ্যারান্টি নেই কারণ আপনার সন্তানের প্রক্রিয়া এখনও চলছে।

দ্বিতীয়টি হ'ল স্টাডাউট এ পঠনযোগ্য স্ট্রিম , সুতরাং 1) ডেটা ইভেন্টটিকে একাধিকবার বলা যেতে পারে এবং 2) কলব্যাকটি স্ট্রিংকে নয়, একটি বাফার দেওয়া হয়। প্রতিকার সহজ; শুধু পরিবর্তন

foo = new run_cmd(
    'netstat.exe', ['-an'], function (me, data){me.stdout=data;}
);

মধ্যে

foo = new run_cmd(
    'netstat.exe', ['-an'], function (me, buffer){me.stdout+=buffer.toString();}
);

যাতে আমরা আমাদের বাফারটিকে স্ট্রিংয়ে রূপান্তর করি এবং সেই স্ট্রিংটি আমাদের স্টাডআউট ভেরিয়েবলের সাথে যুক্ত করি।

তৃতীয়টি হ'ল আপনি কেবলমাত্র জানতে পারবেন আপনি যখন 'শেষ' ইভেন্টটি পাবেন তখন আপনি সমস্ত আউটপুট পেয়েছেন, যার অর্থ আমাদের অন্য শ্রোতা এবং কলব্যাকের প্রয়োজন:

function run_cmd(cmd, args, cb, end) {
    // ...
    child.stdout.on('end', end);
}

সুতরাং, আপনার চূড়ান্ত ফলাফল এটি:

function run_cmd(cmd, args, cb, end) {
    var spawn = require('child_process').spawn,
        child = spawn(cmd, args),
        me = this;
    child.stdout.on('data', function (buffer) { cb(me, buffer) });
    child.stdout.on('end', end);
}

// Run C:\Windows\System32\netstat.exe -an
var foo = new run_cmd(
    'netstat.exe', ['-an'],
    function (me, buffer) { me.stdout += buffer.toString() },
    function () { console.log(foo.stdout) }
);

"কী হবে তার কোনও গ্যারান্টি নেই কারণ আপনার শিশু প্রক্রিয়াটি এখনও চলছে" বন্ধ ... তবে একটি গ্যারান্টি রয়েছে যে এটি সময়ে সেই সময়ে সেট করা হবে না , এবং কেবলমাত্র কলব্যাক ডাকলে কেবল সেট করা হবে, যেমন আপনি অন্য কোথাও নির্দেশ করেছেন

4
এটি কয়েকটি খুব গুরুত্বপূর্ণ জেএস ধারণার দুর্দান্ত ব্যাখ্যা সহ একটি দুর্দান্ত উত্তর। নিস!
L0j1k

1
আপনি ফাংশনটির this.stdout = "";ভিতরে করতে চাইবেন run(), অন্যথায় আপনার উপসর্গ console.log(foo.sdtout);হবে undefined
f1lt3r

78

স্বীকৃত উত্তরের একটি সরলীকৃত সংস্করণ (তৃতীয় পয়েন্ট) সবেমাত্র আমার জন্য কাজ করেছে।

function run_cmd(cmd, args, callBack ) {
    var spawn = require('child_process').spawn;
    var child = spawn(cmd, args);
    var resp = "";

    child.stdout.on('data', function (buffer) { resp += buffer.toString() });
    child.stdout.on('end', function() { callBack (resp) });
} // ()

ব্যবহার:

run_cmd( "ls", ["-l"], function(text) { console.log (text) });

run_cmd( "hostname", [], function(text) { console.log (text) });

1
রিটার্ন মান সম্পর্কে কী, যখন প্রক্রিয়াটি একটি শূন্য নন, আমি কীভাবে এটি পেতে পারি?
ভিটিম.ইস

2
child.stdout.on('close', (errCode) => { console.log(errCode) } )
তুষার গৌতম

52

আমি এটি আরও সংক্ষেপে ব্যবহার করেছি:

var sys = require('sys')
var exec = require('child_process').exec;
function puts(error, stdout, stderr) { sys.puts(stdout) }
exec("ls -la", puts);

এটা পুরোপুরি কাজ করে। :)


1
এটি ভালভাবে কাজ করে এবং কোনও অতিরিক্ত নোড মডিউলগুলির প্রয়োজন নেই। আমি এটা পছন্দ করি!
ভালভরাইন

9
sys.puts()২০১১ সালে (নোড.জেএস ভি0.২.৩ সহ) হ্রাস করা হয়েছিল। console.log()পরিবর্তে আপনার ব্যবহার করা উচিত ।
টিফমন্টিগ

1
এটি আসলে কাজ করে ... তাই আমি ভাবছি, কেন এটি উত্তর নয়? এটি এত সহজ
এক্কিস

কি দারুন!! এই উত্তর নিখুঁত এবং মার্জিত। ধন্যবাদ.
এম জি মধু

43

সহজতম উপায় হ'ল কেবল শেলজেএস লিব ব্যবহার করা ...

$ npm install [-g] shelljs

এক্সেক উদাহরণ:

require('shelljs/global');

// Sync call to exec()
var version = exec('node --version', {silent:true}).output;

// Async call to exec()
exec('netstat.exe -an', function(status, output) {
  console.log('Exit status:', status);
  console.log('Program output:', output);
});

ShellJs.org নোডজেএস ফাংশন হিসাবে ম্যাপযুক্ত অনেকগুলি সাধারণ শেল কমান্ড সমর্থন করে:

  • বিড়াল
  • সিডি
  • chmod
  • CP
  • dirs
  • প্রতিধ্বনি
  • Exec
  • প্রস্থান
  • অনুসন্ধান
  • , grep
  • Ln
  • mkdir,
  • এমভি
  • popd
  • pushd
  • PWD
  • RM
  • sed
  • পরীক্ষা
  • যেটি

শেল স্ক্রিপ্টে শেল স্ক্রিপ্টে একটি পরামিতি যুক্ত করবেন কীভাবে ("foo.sh")?
সিউডোজাচ

1
আপনি শুধু সংযুক্ত করতে পারবেন আপনার আর্গুমেন্ট স্ট্রিং শীর্ষ: shell.exec("foo.sh arg1 arg2 ... ")। আপনার foo.shলিপি $1, $2... ইত্যাদি ব্যবহার করে এটি উল্লেখ করতে পারে
টনি ও'হাগান

আপনি যে কমান্ডটি কার্যকর করতে চেষ্টা করছেন তা ব্যবহারকারীর কাছ থেকে ইনপুট লাগতে থাকলে শেলজেএস এক্সিকিউট () ব্যবহার করবেন না। এই ফাংশনটি প্রকৃতির সাথে ইন্টারেক্টিভ নয়, কারণ এটি কেবল কমান্ড এবং মুদ্রণ আউটপুট নেবে, এর মধ্যে ইনপুট গ্রহণ করতে পারে না। পরিবর্তে চাইল্ড_প্রসেসে বিল্ট ব্যবহার করুন। যেমন https://stackoverflow.com/a/31104898/9749509
এমপিটেল 1

4

আমারও অনুরূপ সমস্যা হয়েছিল এবং আমি এর জন্য নোড এক্সটেনশন লিখে শেষ করেছি। আপনি গিট সংগ্রহস্থলটি পরীক্ষা করে দেখতে পারেন। এটি ওপেন সোর্স এবং ফ্রি এবং সমস্ত ভাল জিনিস!

https://github.com/aponxi/npm-execxi

এক্সেক্সএক্সআই হ'ল একটি নোড এক্সটেনশন যা শেল কমান্ডগুলি একে একে বাস্তবায়িত করার জন্য সি ++ তে লিখিত হয়, কমান্ডের আউটপুটটিকে রিয়েল টাইমে আউটপুট করে। Ptionচ্ছিক শিকলযুক্ত, এবং অপরিশোধিত উপায়ে উপস্থিত রয়েছে; এর অর্থ হ'ল কোনও কমান্ড ব্যর্থ হওয়ার পরে (শৃঙ্খলাবদ্ধ) স্ক্রিপ্টটি থামানো বেছে নিতে পারেন, বা আপনি এমন কিছু চালিয়ে যেতে পারেন যেন কিছুই ঘটেনি!

ব্যবহারের নির্দেশাবলী ReadMe ফাইলে রয়েছে । টান অনুরোধ করতে বা ইস্যু জমা দিতে নির্দ্বিধায়!

আমি ভেবেছিলাম এটির উল্লেখ করা ভাল।


4

@ টনিও-হাগান বোধগম্য shelljsউত্তর, তবে, আমি তার উত্তরের সিঙ্ক্রোনাস সংস্করণটি হাইলাইট করতে চাই:

var shell = require('shelljs');
var output = shell.exec('netstat -rn', {silent:true}).output;
console.log(output);


0

আপনার run_cmdফাংশনে একটি পরিবর্তনশীল দ্বন্দ্ব রয়েছে :

  var me = this;
  child.stdout.on('data', function(me, data) {
    // me is overriden by function argument
    cb(me, data);
  });

কেবল এটিকে এটি পরিবর্তন করুন:

  var me = this;
  child.stdout.on('data', function(data) {
    // One argument only!
    cb(me, data);
  });

ত্রুটিগুলি দেখতে সর্বদা এটি যুক্ত করুন:

  child.stderr.on('data', function(data) {
      console.log( data );
  });

সম্পাদনা করুন আপনার কোডটি ব্যর্থ হয়েছে কারণ আপনি চালনার চেষ্টা করছেন dirযা আলাদা স্ট্যান্ডেলোন প্রোগ্রাম হিসাবে সরবরাহ করা হয় না । এটি cmdপ্রক্রিয়াধীন একটি কমান্ড । আপনি যদি ফাইল সিস্টেমের সাথে খেলতে চান তবে নেটিভ ব্যবহার করুন require( 'fs' )

বিকল্পভাবে (যা আমি প্রস্তাব করি না) আপনি একটি ব্যাচ ফাইল তৈরি করতে পারেন যা আপনি চালাতে পারেন। নোট করুন যে ওএস ডিফল্টরূপে ব্যাচের ফাইলগুলিতে ফায়ার করে cmd


আপনার সহায়তার জন্য আপনাকে ধন্যবাদ ... যাইহোক, আমি চালানোর C:\Windows\System32\netstat.exeপরেও এটি এখনও ফলাফল দেয় না ... আমার সঠিক বাক্য গঠনটি ছিল foo = new run_cmd('netstat.exe', ['-an'], function (me, data){me.stdout=data;});... আমি এখনও এ পর্যন্ত কোনও সফলতা ছাড়াই পুরো পথটি চেষ্টা করেছিলাম
মাইক পেনিংটন

0

আপনি আপনার রান_সেমিডি ফাংশন থেকে আসলে কিছুই ফিরিয়ে দিচ্ছেন না।

function run_cmd(cmd, args, done) {
    var spawn = require("child_process").spawn;
    var child = spawn(cmd, args);
    var result = { stdout: "" };
    child.stdout.on("data", function (data) {
            result.stdout += data;
    });
    child.stdout.on("end", function () {
            done();
    });
    return result;
}

> foo = run_cmd("ls", ["-al"], function () { console.log("done!"); });
{ stdout: '' }
done!
> foo.stdout
'total 28520...'

ঠিক কাজ করে। :)


আমি মনে করি না returnযতক্ষণ আপনি যথাযথভাবে অবজেক্টের বৈশিষ্ট্যগুলি সেট করেছেন ততক্ষণ প্রয়োজন
মাইক পেনিংটন

0

সর্বাধিক সম্মানিত উত্তরের একটি প্রচারিত সংস্করণ:

  runCmd: (cmd, args) => {
    return new Promise((resolve, reject) => {
      var spawn = require('child_process').spawn
      var child = spawn(cmd, args)
      var resp = ''
      child.stdout.on('data', function (buffer) { resp += buffer.toString() })
      child.stdout.on('end', function () { resolve(resp) })
    })
  }

ব্যবহার করা:

 runCmd('ls').then(ret => console.log(ret))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.