node.js সিঙ্ক্রোনালি সিস্টেম কমান্ড চালায়


171

আমার নোড.জেএস ফাংশন দরকার

result = execSync('node -v');

এটি সিঙ্ক্রোনিকভাবে প্রদত্ত কমান্ড লাইনটি কার্যকর করবে এবং সেই কমান্ড পাঠ্যের সাহায্যে সমস্ত ফিরিয়ে দেবে।

পুনশ্চ. সিঙ্ক ভুল। আমি জানি. শুধু ব্যক্তিগত ব্যবহারের জন্য।

হালনাগাদ

এখন আমাদের কাছে মিগুতুজের সমাধান রয়েছে যা আমাদের প্রস্থান কোড দেয়, তবে স্টাডআউট নয়! এখনও আরও সুনির্দিষ্ট উত্তরের জন্য অপেক্ষা করছি।

হালনাগাদ

মিলিগুটজ তার উত্তর আপডেট করেছে এবং সমাধানটি এখানে রয়েছে :)
এছাড়াও, ডিগো.এ. হিসাবে উল্লেখ করা হয়েছে, এখানে স্ট্যান্ড-একা মডিউল এক্সিকিউটি -সিঙ্ক রয়েছে

আপডেট 2014-07-30

শেলজেএস লাইব এসেছিল। এটি আপাতত সেরা পছন্দ বিবেচনা করুন।


আপডেট 2015-02-10

শেষ পর্যন্ত! নোডজেএস 0.12 execSyncস্থানীয়ভাবে সমর্থন করে।
অফিসিয়াল ডক্স দেখুন


26
নিজেকে বোকা হতে দেবেন না, সিঙ্কটি ভুল নয় ... আপনার স্পষ্টত একটি অ্যাসিঙ্ক পদ্ধতিটি কল না করা পর্যন্ত নোডজেএস-এ আপনার সমস্ত কোড সিঙ্ক্রোনালি কার্যকর করা হবে ... যদি সবকিছু অ্যাসিঙ্ক্রোনাস উপায়ে করা হয় তবে কিছুই কখনও করা হত না। এছাড়াও, অ্যাসিনক্রোনাস পদ্ধতিগুলি পছন্দ করার অর্থ এই নয় যে আপনার দীর্ঘ গণনাটি আপনার সার্ভারকে ব্লক করবে না। এটি একটি পছন্দ যে নোডের নির্মাতারা অ্যাসিঙ্কগুলি পাশাপাশি সিঙ্ক্রোনাস ফাইল সিস্টেমের পদ্ধতি সরবরাহ করতে বেছে নিয়েছে কেবল তাদের জন্যও একটি জায়গা আছে তা দেখানোর জন্য যায়।
প্রবাহিত করুন

2
আপনি যে "ইউনিক্স শেল এমুলেশন লাইব্রেরি" এর কথা বলছেন তা কোথায় পাওয়া যাবে?
ফ্লোরিয়ান

@

উত্তর:


153

নোড.জেএস (যেহেতু সংস্করণ 0.12 - তাই কিছু সময়ের জন্য) সমর্থন করে execSync:

child_process.execSync(command[, options])

আপনি এখন সরাসরি এটি করতে পারেন:

const execSync = require('child_process').execSync;
code = execSync('node -v');

এবং এটি আপনি যা প্রত্যাশা করেন তা করবে। (পিতা-মাতার প্রক্রিয়াতে i / o ফলাফলগুলি পাইপ করতে ডিফল্ট)। আপনি spawnSyncএখন করতে পারেন তা নোট করুন ।


6
হতাশার 10 ঘন্টা পরে। ধন্যবাদ ডুড
টম দেব

এই সাব-প্রসেস থেকে আমি কীভাবে সংযোগ বিচ্ছিন্ন করতে পারি?
জুলিয়ানসোটো

@ জুলিয়ানসোটো নোডজেএস.আর.পি.আই.পি
divine

54

ExecSync লাইব্রেরি দেখুন ।

নোড-এফফি সহ এটি করা মোটামুটি সহজ । আমি সার্ভার প্রক্রিয়াগুলির জন্য সুপারিশ করব না, তবে সাধারণ বিকাশের ইউটিলিটিগুলির জন্য এটি কাজ হয়ে যায়। গ্রন্থাগারটি ইনস্টল করুন।

npm install node-ffi

উদাহরণ লিপি:

var FFI = require("node-ffi");
var libc = new FFI.Library(null, {
  "system": ["int32", ["string"]]
});

var run = libc.system;
run("echo $USER");

[জুন ২০১২ সম্পাদনা করুন: কীভাবে STDOUT পাবেন]

var lib = ffi.Library(null, {
    // FILE* popen(char* cmd, char* mode);
    popen: ['pointer', ['string', 'string']],

    // void pclose(FILE* fp);
    pclose: ['void', [ 'pointer']],

    // char* fgets(char* buff, int buff, in)
    fgets: ['string', ['string', 'int','pointer']]
});

function execSync(cmd) {
  var
    buffer = new Buffer(1024),
    result = "",
    fp = lib.popen(cmd, 'r');

  if (!fp) throw new Error('execSync error: '+cmd);

  while(lib.fgets(buffer, 1024, fp)) {
    result += buffer.readCString();
  };
  lib.pclose(fp);

  return result;
}

console.log(execSync('echo $HOME'));

2
আপনি কীভাবে আসলে এ থেকে কিছু প্রেরণ করবেন stdout? আমি যা পেতে পারি তা হ'ল প্রক্রিয়াটি প্রস্থান করার কোড
মার্ক কাহন

@ কলোভস: আমি মনে করি এ্যাসিঙ্ক এটি আরও ভাল হবে। ( ইভো এর উত্তর )
pvorb

@ প্লোয়ারব - হ্যাঁ, আপনি যখন অ্যাসিঙ্ক ব্যবহার করতে পারবেন না তা ছাড়া :)
মার্ক কাহন

1
প্রতিটি পেরেকের জন্য অ্যাসিঙ্ক হাতুড়ি ব্যবহার না করার বৈধ কারণ রয়েছে। উদাহরণস্বরূপ, টেমপ্লেট ইঞ্জিনগুলি এক্সপ্রেস 3 এ অ্যাসিঙ্ক হয় এবং সহায়ক ফাংশনগুলি (স্থানীয়) সিঙ্ক্রোনাস হওয়া দরকার। যদি সেই সহায়িকার ফাংশনগুলিতে উড়ে যাওয়ার সময় অল্প সংক্ষিপ্ত আকারে কম ফাইলগুলি সংকলনের প্রয়োজন হয় তবে কী হবে?
মিগুটোজ

8
আমি ভাবছি কেন এই সরল execSyncঅংশটি নয় child_process। আমি মনে করি এটি.
মাইকেল হার্টল

31

শেলজেএস মডিউলটি ব্যবহার করুন ।

কলব্যাক সরবরাহ না করে এক্সিকিউশন ফাংশন।

উদাহরণ:

var version = exec('node -v').output;

2
নোট করুন যে লেখার সময়, ডক্সগুলি উল্লেখ করে যে সিঙ্ক্রোনাস exec()দীর্ঘ প্রক্রিয়াগুলির জন্য সিপিইউ নিবিড়।
আরম কোচার্যান

1
বিকল্পগুলি, {নীরব: সত্য key কী
নিক

1
এটি কিছু করে (সংক্ষিপ্ত সিনট্যাক্স সরবরাহ ব্যতীত) এটি করে না? const execSync = require('child_process').execSync; code = execSync('node -v');
ব্যবহারকারী2503764

23

নোড.জেএসসে অ্যাসিঙ্কব্লক নামে একটি প্রবাহ নিয়ন্ত্রণের জন্য একটি দুর্দান্ত মডিউল রয়েছে । যদি কোনও ফাংশনে কোড মোড়ানো আপনার ক্ষেত্রে ঠিক থাকে তবে নিম্নলিখিত নমুনা বিবেচনা করা যেতে পারে:

var asyncblock = require('asyncblock');
var exec = require('child_process').exec;

asyncblock(function (flow) {
    exec('node -v', flow.add());
    result = flow.wait();
    console.log(result);    // There'll be trailing \n in the output

    // Some other jobs
    console.log('More results like if it were sync...');
});

1
তিনি সিঙ্ক সংস্করণ সম্পর্কে স্পষ্টভাবে জিজ্ঞাসা করেছিলেন, ফ্লো লাইব্রেরিগুলি নিয়ন্ত্রণ করেন না।
আলেক্সি পেটরুশিন

22
@ অ্যালেক্সেপেট্রুশিন এখানে প্রতিটি প্রশ্ন একটি লক্ষ্য সম্পর্কে, এটি অর্জনের নির্দিষ্ট উপায় সম্পর্কে নয়। যদিও ডাউনভোটিংয়ের জন্য ধন্যবাদ।
নব

1
এছাড়াও, এটি উইন্ডোজ ব্যবহারকারীদের জন্য একটি খুব দরকারী উত্তর; উইন্ডোজ ইনস্টল করা exec-syncবা ffiএকটি বিশাল ওভারহেড (ভিসি ++, এসডিকে, পাইথন, ইত্যাদি) রয়েছে তবে এটি হালকা।
মেনধক

10

উভয়ই নোড.জেজে এটি সম্ভব নয় child_process.spawn এবংchild_process.exec ASYNC হতে স্থল থেকে তৈরী করা হয়েছে।

বিশদ জন্য দেখুন: https://github.com/ry/node/blob/master/lib/child_process.js

আপনি যদি সত্যিই এই ব্লক করতে চান তবে তারপরে যা ঘটতে হবে তার সবকিছু কলব্যাকের মধ্যে রেখে দিন বা একটি ব্লকিং ফ্যাশনে এটি পরিচালনা করতে আপনার নিজের সারি তৈরি করুন, আমি মনে করি আপনি এই কাজের জন্য Async.js ব্যবহার করতে পারেন could

অথবা, আপনার যদি খুব বেশি সময় ব্যয় করতে পারে তবে নোড.জেজে নিজেকে হ্যাক করুন।


12
অদ্ভুত কারণ ফাইল সিস্টেম মডিউলটির সিঙ্ক্রোনাস কল রয়েছে। মৃত্যুদণ্ড কার্যকর করা হচ্ছে না কেন?
আলফ্রেড

4
@ অ্যালফার্ড সিঙ্ক এফএস কলগুলি মূলত প্রোগ্রামের শুরুতে কনফিগার লোড করার জন্য সেখানে থাকে।
আইভো ওয়েটজেল

3
@ আইভোওয়েটজেল - তীব্র ঝোঁক ... আমরা কখনও কিছু বলতে অসম্ভব বলা শিখিনি? ;) আমার সমাধানটি নীচে দেখুন।
মার্কাস পোপ

1
@ আইভোওয়েজেল "সিঙ্ক এফএস কল ..." - ঠিক আছে, এবং কখনও কখনও আপনি বলতে চান যে প্রোগ্রাম শুরুতে কিছু সংকলন করতে এবং কমপ্লিট করার পরে চালিয়ে যেতে চান। There সেখানে সিঙ্ক এফএস কল রয়েছে, একটি সিঙ্ক এক্সিকিউটিভ নেই একটি তদারকি মত চেহারা। আমি সবই অ্যাসিক্রোনাসের জন্য, তবে সিনক্রোনাসের পক্ষে এর পক্ষে ভাল এবং ব্যবহারের কেস রয়েছে। অবশ্যই এটি একটি ন্যায়বিচারমূলক পদ্ধতিতে ব্যবহার করা উচিত।
প্রবাহিত করুন

অ্যাসিঙ্ক ঠিক আছে, তবে উইজেটবি যদি উইজেটএর চূড়ান্ত ফলাফলের উপর নির্ভর করে তবে বিশ্বের সমস্ত অ্যাসিঙ্ক কাজটি করবে না। কখনও কখনও প্রক্রিয়াগুলি সিঙ্ক্রোনাস হতে হয়। তাত্পর্যপূর্ণভাবে রান্না করার চেষ্টা করুন। ;)
লয়েড সারজেন্ট

9

এটি আমি খুঁজে পাওয়া সবচেয়ে সহজ উপায়:

এক্সিকিউটি -সিঙ্ক : https://github.com/jeremyfa/node-exec-sync
(
এক্সিকিউনসিঙ্কের সাথে বিভ্রান্ত হওয়ার দরকার নেই)) শেল কমান্ড সিঙ্ক্রোনসিভ করে চালিত করুন । এটিকে মাইগ্রেশন স্ক্রিপ্ট, ক্লিপ প্রোগ্রামগুলির জন্য ব্যবহার করুন তবে নিয়মিত সার্ভার কোডের জন্য নয়।

উদাহরণ:

var execSync = require('exec-sync');   
var user = execSync('echo $USER');
console.log(user);

7

কেবল যুক্ত করার জন্য যদিও আপনার কয়েকটি ব্যবহারের ক্ষেত্রে আপনার এটি ব্যবহার করা উচিত, spawnSync/ execFileSync/ এই কমিটগুলিতে নোড.জেগুলি execSyncযুক্ত করা হয়েছে: https://github.com/joyent/node/compare/d58c206862dc...e8df2676748e


এর অর্থ কি আমরা বাক্সের বাইরে v0.12 এ রেখে যাব?
14:56

@ বিশৃঙ্খল হ্যাঁ: বল্লুপ
স্ট্রংব্লগ


3

আমি "synchronous"কলব্যাক ফাংশন শেষে স্টাফ বাস্তবায়ন করতে অভ্যস্ত হয়েছি । খুব সুন্দর না, তবে এটি কাজ করে। আপনার যদি কমান্ড লাইন মৃত্যুদন্ডের ক্রমটি প্রয়োগ করতে হয় তবে আপনাকে execকিছু নামকৃত ফাংশনটি মোড়তে হবে এবং পুনরাবৃত্তভাবে এটি কল করতে হবে। এই নিদর্শনটি আমার কাছে ব্যবহারযোগ্য বলে মনে হচ্ছে:

SeqOfExec(someParam);

function SeqOfExec(somepParam) {
    // some stuff
    // .....
    // .....

    var execStr = "yourExecString";
    child_proc.exec(execStr, function (error, stdout, stderr) {
        if (error != null) {
            if (stdout) {
                throw Error("Smth goes wrong" + error);
            } else {
                // consider that empty stdout causes
                // creation of error object
            }
        }
        // some stuff
        // .....
        // .....

        // you also need some flag which will signal that you 
        // need to end loop
        if (someFlag ) {
            // your synch stuff after all execs
            // here
            // .....
        } else {
            SeqOfExec(someAnotherParam);
        }
    });
};

3

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

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

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

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

সম্পাদনা করুন: তবে এটি এখনও স্টডআউট ফিরিয়ে দেয় না ... কেবল রিয়েল-টাইমে তাদের আউটপুট করে। এটা এখন। ঠিক আছে, আমি আজই এটি প্রকাশ করেছি। আমরা এটি নির্মাণ করতে পারে।

যাইহোক, আমি ভেবেছিলাম এটি উল্লেখ করা ভাল।


এটি ঠিক আমি যা খুঁজছিলাম ছিল। এটি করার জন্য সময় দেওয়ার জন্য আপনাকে ধন্যবাদ।
thealfreds

আমি একমাত্র জিনিসটি খুঁজে বের করতে এবং প্রয়োগ করতে পারি নি তা হ'ল বিভিন্ন নোডেজ সংস্করণগুলির জন্য বিল্ড কনফিগারেশন। আমি অনুমান করি যে আমি এটি নোড ০.৮ ( travis-ci.org/aponxi/npm-execxi/builds/5248535 ) এ লিখেছি যাতে যতক্ষণ npm installসাফল্য হয় (অন্য কথায় প্লাগইন সংকলন হিসাবে), তবে প্রোডাকশনে যাওয়া ভাল go বিভিন্ন নোডেজ সংস্করণ লক্ষ্যবস্তু করা ছাড়াও, আমি বলতে পারি এটি উত্পাদন জন্য প্যাচ আপ, বা এটি বেশ স্থিতিশীল। যদি কোনও বাগ থাকে তবে আপনি একটি টানা অনুরোধ প্রেরণ করতে বা গিথুব এ একটি সমস্যা পোস্ট করতে পারেন :)
লোগান

1

আপনি নোডজে যেমন সিঙ্ক্রোনাস শেল অপারেশন করতে পারেন:

var execSync = function(cmd) {

    var exec  = require('child_process').exec;
    var fs = require('fs');

    //for linux use ; instead of &&
    //execute your command followed by a simple echo 
    //to file to indicate process is finished
    exec(cmd + " > c:\\stdout.txt && echo done > c:\\sync.txt");

    while (true) {
        //consider a timeout option to prevent infinite loop
        //NOTE: this will max out your cpu too!
        try {
            var status = fs.readFileSync('c:\\sync.txt', 'utf8');

            if (status.trim() == "done") {
                var res = fs.readFileSync("c:\\stdout.txt", 'utf8');
                fs.unlinkSync("c:\\stdout.txt"); //cleanup temp files
                fs.unlinkSync("c:\\sync.txt");
                return res;
            }
        } catch(e) { } //readFileSync will fail until file exists
    }

};

//won't return anything, but will take 10 seconds to run
console.log(execSync("sleep 10")); 

//assuming there are a lot of files and subdirectories, 
//this too may take a while, use your own applicable file path
console.log(execSync("dir /s c:\\usr\\docs\\"));

সম্পাদনা করুন - এই উদাহরণটি উইন্ডোজের পরিবেশের জন্য বোঝানো হয়েছে, প্রয়োজনে আপনার নিজের লিনাক্সের জন্য সামঞ্জস্য করুন


হ্যাঁ, এবং আপনার সিপিইউ যত তাড়াতাড়ি তলব করতে পারে ... তবে আরে যখন আপনার কোনও খারাপ কাজ করার "দরকার" হয়, তখন শয়তান আপনার লোকটি ঠিক?
মার্কাস পোপ

ঠিক আছে, এটি খাঁটি মন্দ, তবে দুর্দান্ত। আমার একটি ফাইল সিস্টেমের ইভেন্ট ব্রাউজারিফাই.অন ('রেজিস্টার') হ্যান্ডেল করার জন্য এটি দরকার ছিল, এতে কলব্যাক নেই। আমার দিন বাঁচা!
রবার্ট গোল্ড

এটি জাভাস্ক্রিপ্ট ইঞ্জিনগুলিতে কেন কাজ করে তা ব্যাখ্যা করতে পারেন? পরেরটিতে এক্সিকিউট করার সময় লুপটি একই টিকটিতে অসীমভাবে কার্যকর করা উচিত নয়?
Badunk

ব্যস্ত অপেক্ষা করে সিপিইউকে সর্বাধিক আউট করা খারাপ ডিজাইন।
লুই

@ লুই-ডোমিনিক ডুবউ অবশ্যই, তবে এমন কোনও বিকল্প নেই যা কোনও তৃতীয় পক্ষের উত্সের উপর নির্ভর করে না যা ক্রস প্ল্যাটফর্মের সাথে সামঞ্জস্যপূর্ণ বা নাও হতে পারে। এটি সিপিইউ থেকে বেরিয়ে আসার ক্ষেত্রেও সত্য নয় কারণ ওএস নোডেজ প্রক্রিয়াটিকে সম্পূর্ণ অগ্রাধিকার দেয় না। আমি মনে করি শেল অপের সিঙ্ক বাস্তবায়ন দিগন্তের দিকে বা সম্ভবত এখানে ইতিমধ্যে।
মার্কাস পোপ

1

আমার আসলে একটি পরিস্থিতি ছিল যেখানে আমার প্রয়োজন ছিল একের পর এক প্যাকেজ থেকে একের পর এক কমান্ড চালানো।

সুতরাং আমি এটাই নিয়ে এসেছি:

#cmds.coffee
childproc = require 'child_process'

exports.exec = (cmds) ->
  next = ->
    if cmds.length > 0
      cmd = cmds.shift()
      console.log "Running command: #{cmd}"
      childproc.exec cmd, (err, stdout, stderr) ->
        if err? then console.log err
        if stdout? then console.log stdout
        if stderr? then console.log stderr
        next()
    else
      console.log "Done executing commands."

  console.log "Running the follows commands:"
  console.log cmds
  next()

আপনি এটি এর মতো ব্যবহার করতে পারেন:

require('./cmds').exec ['grunt coffee', 'nodeunit test/tls-config.js']

সম্পাদনা: যেমনটি উল্লেখ করা হয়েছে, এটি আসলে আউটপুট ফেরত দেয় না বা কোনও নোড প্রোগ্রামে কমান্ডের ফলাফল ব্যবহারের অনুমতি দেয় না। এর জন্য অন্য একটি ধারণা লাইভস্ক্রিপ্টের ব্যাককলগুলি ব্যবহার করা। http://livescript.net/


ধন্যবাদ, কিন্তু এই আপনার কোড যেহেতু কোন উত্তর না সিরিজে কমান্ড রান অ্যাসিঙ্ক্রোনাস
disfated

আমার উদাহরণ অনুযায়ী আপনার যদি সিরিজ কমান্ডের একটি সিরিজ কার্যকর করতে হয় তবে এটি কাজ করবে। আমি মনে করি আপনার প্রশ্নটি আমি ভুল বুঝেছি, দুঃখিত। আমি উত্তরে আরও একটি ধারণা যুক্ত করেছি।
জেসন লাইভসে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.