الفرق بين المراجعتين لصفحة: «Node.js/child process»

من موسوعة حسوب
إضافة محتويات الصفحة.
 
سطر 176: سطر 176:
</syntaxhighlight>'''تحذير''': إن مُرِّرت القيمة المنطقيَّة <code>true</code> للخيار <code>shell</code>، فلا تمرِّر مدخلات المستخدم إلى هذه الدالة مطلقًا ما لم تتحقَّق من صحتها وسلامتها، إذ يستطيع المستخدم التحايل وإدخال محارف خاصَّة بالصدفة (metacharacters) -مثل <code>:</code> أو <code>&</code>- مما يسمح له بتشغيل أوامر أخرى.
</syntaxhighlight>'''تحذير''': إن مُرِّرت القيمة المنطقيَّة <code>true</code> للخيار <code>shell</code>، فلا تمرِّر مدخلات المستخدم إلى هذه الدالة مطلقًا ما لم تتحقَّق من صحتها وسلامتها، إذ يستطيع المستخدم التحايل وإدخال محارف خاصَّة بالصدفة (metacharacters) -مثل <code>:</code> أو <code>&</code>- مما يسمح له بتشغيل أوامر أخرى.


=== <code>child_process.fork(modulePath[, args][, options])</code> ===
=== <code>‎child_process.fork(modulePath[, args][, options])</code> ===
{| class="wikitable mw-collapsible"
{| class="wikitable mw-collapsible"
|+سجل التغييرات
|+سجل التغييرات

مراجعة 13:17، 29 يوليو 2018

الاستقرار: 2-مستقر

توفِّر الوحدة child_process القدرة على توليد (spawn) عمليات أبناء بطريقةٍ مشابهةٍ  -وليست مماثلة- للدالة popen(3)‎، إذ يمكن للدالة child_process.spawn()‎ أن توفِّر هذه الإمكانيَّة في المقام الأول:

const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

تُنشَأ أنابيبٌ (pipes) لمجرى الدخل القياسي (stdin) ومجرى الخرج القياسي (stdout) ومجرى الخطأ القياسي (stderr) بين العمليَّة الأب في Node.js والعمليَّة الابن المولدة. إنّ لهذه الأنابيب قدرةٌ محدودةٌ (متعلقة بالمنصة المستعملة). إن حصل فائض عند كتابة العمليَّة الابن على مجرى الخرج القياسي يتجاوز القدرة الحديَّة تلك دون إظهار المخرجات، فستُوقف العمليَّة الابن عمليَّة انتظار مخزن الأنابيب (pipe buffer) لقبول المزيد من البيانات. هذا السلوك مماثل لسلوك الأنابيب في الصدفة (shell). استعمل الخيار { stdio: 'ignore'‎ } إن كنت لا تود استعمال المخرجات والاستفادة منها.

يولِّد التابع child_process.spawn()‎ العمليات الأبناء بشكل غير متزامن ودون منع حلقة أحداث Node.js. أمَّا التابع child_process.spawnSync()‎ فيملك وظيفة مشابهة إذ يولِّد العمليات الأبناء ولكن بشكل متزامن، إذ يمنع حلقة الأحداث (event loop) حتى تنتهي علمية التوليد أو يتم مقاطعتها.

توفِّر الوحدة child_process بدائل متزامنة وغير متزامنة للتابعين child_process.spawn()‎ و child_process.spawnSync()‎. انتبه إلى أنَّ هذه البدائل تُنفَّذ فوق child_process.spawn()‎ أو child_process.spawnSync()‎.

  • التابع child_process.exec()‎: يولِّد صدفةً (shell) ثمَّ يُنفِّذ أمرًا داخل هذه الصدفة مع تمرير مجرى الخرج والدخل القياسيين إلى دالة رد نداء عند الاكتمال.
  • التابع child_process.execFile()‎: مشابهٌ للتابع السابق باستثناء أنَّه يولِّد الأمر مباشرةً دون توليد صدفةٍ أولًا.
  • التابع child_process.fork()‎: يولِّد عمليَّة Node.js جديدة ويستدعي وحدة محددَّة مع وجود قناة اتصال IPC مُنشَأة تسمح بإرسال الرسائل بين العمليَّة الأب والابن.
  • التابع child_process.execSync()‎: نسخةٌ متزامنة من التابع child_process.exec()‎ الذي يمنع حلقة أحداث Node.js.
  • التابع child_process.execFileSync()‎: نسخةٌ متزامنة من التابع child_process.execFile()‎ الذي سيمنع حلقة أحداث Node.js.

قد تكون التوابع المتزامنة المقابلة في أغلب حالات الاستخدام، مثل أتمتة سكربتات الصدفة، ملائمةٌ أكثر. على أي حال، إنَّ لاستعمال التوايع المتزامنة أثرٌ كبيرٌ في أغلب الأوقات على الأداء وذلك عائد إلى توقف حلقة الأحداث (event loop) عند اكتمال العمليَّات المولدة.

إنشاء عملية غير متزامنة

تتبع الدوال hild_process.spawn()‎، و child_process.fork()‎، و child_process.exec()‎، و child_process.execFile()‎ جميعها نمط البرمجة غير المتزامنة الاعتيادي لواجهات Node.js البرمجيَّة الأخرى.

يعيد كلٌّ من تلك التوابع نسخةً من ChildProcess. تُنفِّذ (implement) هذه الكائنات الواجهة البرمجيَّة EventEmitter متيحةً بذلك للعملية الأب بتسجيل الدوال المستمعة التي تستدعى عند وقوع أحداث معيَّنة خلال دورة حياة العمليَّة الابن.

أضف إلى ذلك أنَّ التابعين child_process.exec()‎ و child_process.execFile()‎ يسمحان بتحديد دالة رد نداء callback اختياريَّة تُستدعَى عند انتهاء العمليَّة الابن.

توليد الملفان ‎.bat و ‎.cmd في ويندوز

جوهر الاختلاف بين التابع child_process.exec()‎ والتابع child_process.execFile()‎ يمكن أن يتفاوت من منصة لأخرى. في الأنظمة الشبيهة بيونكس (مثل يونكس، ولينكس، وماك)، يكون التابع child_process.execFile()‎ أكثر كفاءةً لأنَّه لا يولد صدفةً بشكل افتراضي. أمَّا في نظام التشغيل ويندوز، لا يكون الملفان ‎.bat و ‎.cmd قابلين للتنفيذ من تلقاء نفسيهما بدون وجود طرفيَّة، لذا لا يمكن تشغيلهما باستعمال child_process.execFile()‎. على أي حال، يمكن استدعاء هذين الملفين باستعمال التابع child_process.spawn()‎ مع الخيار shell، أو التابع child_process.exec()‎، أو عبر توليد العمليَّة cmd.exe ثمََّّ تمرير الملف ‎.bat أو الملف ‎.cmd كوسيط (هذا بالضبط ما يفعله الخيار shell والتابع child_process.exec()‎). إن احتوى اسم السكربت، عند استعمال أي طريقة، على أيَّة مسافات فارغة، فجب حينئذٍ أن يكون ذلك الاسم بين علامتي اقتباس.

// ... في ويندوز فقط
const { spawn } = require('child_process');
const bat = spawn('cmd.exe', ['/c', 'my.bat']);

bat.stdout.on('data', (data) => {
  console.log(data.toString());
});

bat.stderr.on('data', (data) => {
  console.log(data.toString());
});

bat.on('exit', (code) => {
  console.log(`Child exited with code ${code}`);
});

child_process.exec(command[, options][, callback])‎

سجل التغييرات
الإصدار التغييرات
v8.8.0 إضافة المعامل windowsHide.
v0.1.90 إضافة هذا التابع.
  • command: ‏<string> سلسلةٌ نصيةٌ تُمثِّل الأمر المراد تنفيذه مع وسائط مفصولة بفراغ.
  • options: ‏<Object> كائنٌ من النوع Object يمكن أن يحتوي على الخيارات التالية:
    • cwd: ‏<string> سلسلةٌ نصيةٌ تمثِّل مجلد العمل الحالي للعملية الابن. القيمة الافتراضيَّة هي: null.
    • env: ‏<Object> كائنٌ يتكون من الأزواج مفتاح/قيمة يمثِّل البيئة.
    • encoding: ‏<string> سلسلةٌ نصيةٌ تمثِّل الترميز المستعمل. القيمة الافتراضيَّة هي: 'utf8'.
    • shell: ‏<string> سلسلةٌ نصيةٌ تحدِّد الصدفة المراد تنفيذ الأمر ضمنها (ارجع إلى القسم «متطلبات الصدفة» والقسم «صدفة ويندوز الافتراضيَّة» في الأسفل للمزيد من التفاصيل). القيمة الافتراضيَّة هي: '‎/bin/sh' في يونكس والأنظمة الشبيهة به، أو process.env.ComSpec في ويندوز.
    • timeout: ‏<number> الفترة الزمنيَّة القصوى بالميلي ثانية التي يُسمَح فيها للعمليَّة بالعمل. القيمة الافتراضيَّة هي: 0.
    • maxBuffer: ‏<number> عددٌ يمثِّل أكبر حجم مسموحٍ به للبيانات بالبايت في مجريي الخرج والخطأ القياسيين. في حال تجاوز هذه القيمة، ستُنهَى العمليَّة الابن مباشرةً. ارجع إلى القسم «الخيار maxBuffer والترميز الموحَّد». القيمة الافتراضيَّة هي: 200 * 1024.
    • killSignal: ‏<string> | ‏<integer> قيمة الإشارة المراد استعمالها عندما يتم قتل (kill) العمليَّة المُولَّدة. القيمة الافتراضيَّة هي: 'SIGTERM'.
    • uid: ‏<number> عددٌ يحدِّد مُعرِّف المستخدم المالك للعملية (ارجع إلى setuid(2)‎).
    • gid: ‏<number> عددٌ يحدِّد مُعرِّف المجموعة المالكة للعملية (ارجع إلى setgid(2)‎).
    • windowsHide: ‏<boolean> قيمةٌ منطقيةٌ تتحكم بإظهار وإخفاء نافذة الطرفيَّة للعمليَّة الفرعية التي ستُنشأ دومًا بشكل اعتيادي في أنظمة ويندوز. القيمة الافتراضيَّة هي: false.
  • callback: ‏<Function> دالةٌ تستدعى مع المخرجات عند انتهاء العمليَّة.
  • نوع القيم المعادة: <ChildProcess>

يولدِّ هذا التابع صدفةً ثمََّّ ينفِّذ الأمر command المُعطى ضمنها مع تخزين أية مخرجات ناتجة. يعالج الأمر command المعطى المُمرَّر إلى الدالة exec مباشرةً من طرف الصدفة، ويجب الانتباه إلى المحارف الخاصَّة والتعامل معها (تهريبها مثلًا) بشكل صحيح وفقًا للصدفة المستعملة آنذاك:

exec('"/path/to/test file/test.sh" arg1 arg2');
// استعملت علامة الاقتباس المزدوجة، لذا لن تُفسَّر المسافة الموجودة في المسار على
// أنها وسائط متعددة

exec('echo "The \\$HOME variable is $HOME"');
// وإظهاره حرفيًّا أولًا ثمََّّ إظهار قيمته ثانيًّا $HOME استُعمل محرف التهريب لتهريب المتغير

تحذير: لا تمرِّر مدخلات المستخدم إلى هذه الدالة مطلقًا ما لم تتحقَّق من صحتها وسلامتها، إذ يستطيع المستخدم التحايل وإدخال محارف خاصَّة بالصدفة (metacharacters) -مثل : أو &- مما يسمح له بتشغيل أوامر أخرى.

إن أعطيت دالة رد النداء callback، فستُستدعى مع الوسائط (error, stdout, stderr). عند النجاح، ستكون قيمة الوسيط error قيمةً عدميَّةً null. أمَّا في حالة وجود خطأ، فسيكون الوسيط error نسخةً من Error. ستكون الخاصِّيَّة error.code هي حالة الخروج من العمليَّة الابن بينما ستُعيَّن الخاصِّيَّة error.signal إلى الإشارة (signal) التي أَنهت العمليَّة. يشير أي حالة خروج مغاير للقيمة 0 إلى حصول خطأٍ ما.

سيحتوي الوسيطان stdout و stderr المُمرَّران إلى دالة رد النداء على مخرجات العمليَّة الابن التي ترسلها إلى مجريَي الخرج والخطأ القياسيين. ستفك Node.js ترميز تلك المخرجات باستعمال الترميز UTF-8 افتراضيًّا ثمَّ تضعها في سلسلة نصية وتمرِّرها إلى دالة رد النداء. إن أردت استعمال ترميز مختلف عن الترميز UTF-8، فحدِّد هذا الترميز البديل الذي تريد استعماله في الخيار encoding. في حال أعطيت القيمة 'buffer' إلى الخيار encoding أو أعطي اسم ترميز لم يُتعرَّف عليه، فسيُمرَّر حينئذٍ الكائن Buffer إلى دالة رد النداء بدلًا من ذلك.

const { exec } = require('child_process');
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
  if (error) {
    console.error(`exec error: ${error}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.log(`stderr: ${stderr}`);
});

إن كانت قيمة المعامل timeout أكبر من الصفر، فستُرسِل العمليَّة الأب إشارةً محدَّدةً بالخيار killSignal (القيمة الافتراضيَّة له هي الإشارة 'SIGTERM') إن تجاوزت أثناء عملها المهلة الزمنية timeout المعطاة بالميلي ثانية.

لا يستبدل التابع child_process.exec()‎ العمليَّة الموجودة آنذاك، وتُستعمَل صدفةٌ لتنفيذ الأمر خلافًا لاستدعاء النظام للدالة exec(3)‎ في معيار POSIX.

إن استدعيت نسخة util.promisify()‎ من هذا التابع، فسيُعيد كائنًا من النوع Promise مع الخاصِّيَّتين stdout و stderr. عند حصول خطأٍ ما (يشمل ذلك أي خطأ ناتج عن إعادة حالة خروج مغايرة للصفر)، فسيُعاد كائن Promise مرفوض مع قيمة الكائن error نفسه المُعطى في دالة رد النداء ولكن مع إضافة الخاصِّيَّتين stdout و stderr.

const util = require('util');
const exec = util.promisify(require('child_process').exec);

async function lsExample() {
  const { stdout, stderr } = await exec('ls');
  console.log('stdout:', stdout);
  console.log('stderr:', stderr);
}
lsExample();

child_process.execFile(file[, args][, options][, callback])‎

سجل التغييرات
الإصدار التغييرات
v8.8.0 إضافة المعامل windowsHide.
v0.1.91 إضافة هذا التابع.
  • file: ‏<string> سلسلةٌ نصيةٌ تحوي اسم أو مسار الملف القابل للتنفيذ المراد تشغيله.
  • args: ‏<string[]‎> قائمةٌ من سلاسل نصية تمثِّل الوسائط.
  • options: ‏<Object> كائنٌ من النوع Object يمكن أن يحتوي على الخيارات التالية:
    • cwd: ‏<string> سلسلةٌ نصيةٌ تمثِّل مجلد العمل الحالي للعملية الابن. القيمة الافتراضيَّة هي: null.
    • env: ‏<Object> كائنٌ يتكون من الأزواج مفتاح/قيمة يمثِّل البيئة.
    • encoding: ‏<string> سلسلةٌ نصيةٌ تمثل الترميز المراد استعماله. القيمة الافتراضيَّة هي: 'utf8'.
    • timeout: ‏<number> الفترة الزمنية القصوى بالميلي ثاينة التي يُسمَح فيها للعملية بالعمل. القيمة الافتراضيَّة هي: 0.
    • maxBuffer: ‏<number> عددٌ يمثِّل أكبر حجم مسموحٍ به للبيانات بالبايت في مجريي الخرج والخطأ القياسيين. في حال تجاوز هذه القيمة، ستُنهَى العمليَّة الابن مباشرةً. ارجع إلى القسم «الخيار maxBuffer والترميز الموحد». القيمة الافتراضيَّة هي: 200 * 1024.
    • killSignal: ‏<string> | ‏<integer> قيمة الإشارة المراد استعمالها عندما يتم قتل (kill) العمليَّة المولدة.  القيمة الافتراضيَّة هي: 'SIGTERM'.
    • uid: ‏<number> عددٌ يحدِّد مُعرِّف المستخدم المالك للعملية (ارجع إلى setuid(2)‎).
    • gid: ‏<number> عددٌ يحدِّد مُعرِّف المجموعة المالكة للعملية (ارجع إلى setgid(2)‎).
    • windowsHide: ‏<boolean> قيمةٌ منطقيةٌ تتحكم بإظهار وإخفاء نافذة الطرفية للعملية الفرعية التي ستُنشأ دومًا بشكل اعتيادي في أنظمة ويندوز. القيمة الافتراضيَّة هي: false.
    • windowsVerbatimArguments: ‏<boolean> قيمة منطقية تحدِّد إن كان يراد اقتباس أو تهريب الوسائط في ويندوز أم لا. يتجاهل هذا الخيار في الأنظمة الشبيهة بيونكس. القيمة الافتراضيَّة في: false.
    • shell: ‏<boolean> | ‏<string> إن كانت true، فسينفذ الأمر command داخل صدفةٍ. ستستعمل '‎/bin/sh' في يونكس والأنظمة الشبيهة به، و process.env.ComSpec في ويندوز، ويمكن تحديد صدفة أخرى بتمرير سلسلة نصية لهذا الخيار. ارجع إلى القسم «متطلبات الصدفة» والقسم «صدفة ويندوز الافتراضيَّة» في الأسفل للمزيد من التفاصيل. القيمة الافتراضيَّة هي: false (عدم استعمال صدفة).
  • callback: ‏<Function> دالةٌ تستدعى مع المخرجات عند انتهاء العمليَّة.
  • نوع القيم المعادة: <ChildProcess>

يشبه هذا التابعُ التابعَ child_process.exec()‎ في جميع النواحي باستثناء أنَّه لا يولِّد صدفةً بشكل افتراضي. عوضًا عن ذلك، سيُنفَّذ الملف file المحدَّد مباشرةً كعملية جديدة مما يجعل هذا التابع أكثر كفاءةً من نظيره child_process.exec()‎.

يدعم هذا التابع المعاملات نفسها التي يدعمها التابع child_process.exec()‎. وبما أنَّه لا تولَّد صدفةٌ، فإنَّ بعض السلوكيات مثل إعادة توجيه المدخلات والمخرجات وتنفيذ الملف في النطاق العام (file globbing) غير مدعومة.

const { execFile } = require('child_process');
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
  if (error) {
    throw error;
  }
  console.log(stdout);
});

سيحتوي الوسيطان stdout و stderr الممرَّران إلى دالة رد النداء على مخرجات العمليَّة الابن التي ترسلها إلى مجرى الخرج والخطأ القياسيين. ستفك Node.js ترميز تلك المخرجات باستعمال الترميز UTF-8 افتراضيًّا ثمَّ تضعها في سلسلة نصية وتمرِّرها إلى دالة رد النداء. إن أردت استعمال ترميز مختلف عن الترميز UTF-8، فحدِّد هذا الترميز البديل الذي تريد استعماله في الخيار encoding. في حال أُعطيت القيمة 'buffer' إلى الخيار encoding أو أعطي اسم ترميز لم يُتعرَّف عليه، فسيمرَّر حينئذٍ الكائن Buffer إلى دالة رد النداء بدلًا من ذلك. إن استدعيت نسخة util.promisify()‎ من هذا التابع، فسيعيد كائنًا من النوع Promise مع الخاصِّيَّتين stdout و stderr. عند حصول خطأ ما (يشمل ذلك أي خطأ ناتج عن إعادة حالة خروج مغايرة للصفر)، فسيُعاد كائن Promise مرفوض مع قيمة الكائن error نفسه المعطى في دالة رد النداء ولكن مع إضافة الخاصَّيِّتين stdout و stderr.

const util = require('util');
const execFile = util.promisify(require('child_process').execFile);
async function getVersion() {
  const { stdout } = await execFile('node', ['--version']);
  console.log(stdout);
}
getVersion();

تحذير: إن مُرِّرت القيمة المنطقيَّة true للخيار shell، فلا تمرِّر مدخلات المستخدم إلى هذه الدالة مطلقًا ما لم تتحقَّق من صحتها وسلامتها، إذ يستطيع المستخدم التحايل وإدخال محارف خاصَّة بالصدفة (metacharacters) -مثل : أو &- مما يسمح له بتشغيل أوامر أخرى.

‎child_process.fork(modulePath[, args][, options])

سجل التغييرات
الإصدار التغييرات
v8.0.0 أصبح بالإمكان أن يكون المعامل stdio سلسلةً نصيةً.
v6.4.0 أضيف المعامل stdio.
v0.5.0 أضيف هذا التابع.
  • modulePath: ‏<string> الوحدة المراد تشغيلها في العمليَّة الابن.
  • args: ‏<string[]‎> قائمة سلاسل نصية تمثِّل الوسائط.
  • options: ‏<Object> كائنٌ من النوع Object يمكن أن يحتوي على الخيارات التالية:
    • cwd: ‏<string> سلسلةٌ نصيةٌ تمثل مجلد العمل الحالي للعملية الابن. القيمة الافتراضيَّة هي: null.
    • env: ‏<Object> كائنٌ يتكون من الأزواج مفتاح/قيمة يمثِّل البيئة.
    • execPath: ‏<string> أمرٌ قابلٌ للتنفيذ يستعمل لإنشاء العمليَّة الابن.
    • execArgv: ‏<string[]‎> قائمة سلاسل نصية تمثِّل الوسائط المراد تمريرها إلى العمليَّة الابن المنشأة. القيمة الافتراضيَّة هي: process.execArgv.
    • silent: ‏<boolean> إن كان true، فستُحوَّل مجاري الدخل والخرج والخطأ القياسية إلى العمليَّة الأب. خلا ذلك، ستُورث تلك المجاري من العمليَّة الأب (ارجع إلى الخيار 'pipe' والخيار 'inherit' في مجاري الدخل والخرج القياسية (stdio) للتابع child_process.spawn()‎ للمزيد من التفاصيل). القيمة الافتراضيَّة هي: false.
    • stdio: ‏<Array> | ‏<string> عندما يُعطى هذا الخيار، سيُتجاهَل الخيار silent. إن أعطيت مصفوفة من المتغيرات، فيجب أن تحتوي على عنصر واحد مع القيمة 'ipc' مثل [0, 1, 2, 'ipc'] وإلا سيرمى خطأٌ. ارجع إلى القسم «الخيار options.stdio» في التابع child_process.spawn()‎ للمزيد من التفاصيل.
    • windowsVerbatimArguments: ‏<boolean> قيمةٌ منطقيَّةٌ تحدِّد إن كان يراد اقتباس أو تهريب الوسائط في ويندوز أم لا. يُتجاهل هذا الخيار في الأنظمة الشبيهة بيونكس. القيمة الافتراضيَّة في: false.
    • uid: ‏<number> عددٌ يحدِّد مُعرِّف المستخدم المالك للعملية (ارجع إلى setuid(2)‎).
    • gid: ‏<number> عددٌ يحدِّد مُعرِّف المجموعة المالكة للعملية (ارجع إلى setgid(2)‎).
  • نوع القيمة المعادة: <ChildProcess>

التابع child_process.fork()‎ هو حالةٌ خاَّصةٌ من التابع child_process.spawn()‎ يُستعمَل خصيصًا لتوليد عمليات Node.js جديدة. يعيد هذا التابع الكائن ChildProcess مثل التابع child_process.spawn()‎ تمامًا. يمتلك الكائن ChildProcess المعاد قناة اتصال إضافيَّة مضمَّنة فيه تسمح للرسائل بأن تمرَّر ذهابًأ وإيابًا بين العمليَّة الأب والعمليَّة الابن. للمزيد من التفاصيل، ارجع إلى التابع subprocess.send()‎.

ينبغي أن تتذكر دومًا أن العمليَّة الابن المولدة في Node.js هي مستقلة كليًّا عن العمليَّة الأب باستثناء قناة التواصل IPC المنشأة بينهما. يكون لكل عمليَّة ذاكرةٌ خاصَّةٌ بها مع نُسَخ V8 خاصَّة بهم أيضًا. لمَّا كان هذا الأمر يتطلب عمليات حجز إضافية للذاكرة، فلا ينصح بتوليد عدد كبير من العمليات الأبناء باستعمال هذا التابع.

سيولد التابع child_process.fork()‎ نسخ جديدة من Node.js افتراضيًّا باستعمال الخاصِّيَّة process.execPath للعملية الأب. تسمح الخاصِّيَّة execPath ضمن الكائن options باستعمال مسار تنفيذ بديل.

عمليات Node.js التي بُدئت مع تحديد قيمة مخصَّصة للخاصِّيَّة execPath ستوصل مع العمليَّة الأب باستعمال واصف الملف (fd) المُعرَّف عبر متغير البيئة NODE_CHANNEL_FD في العمليَّة الابن.

لا ينسخ التابع child_process.fork()‎ العمليَّة الحالية خلافًا للدالة fork(2)‎ في أنظمة POSIX.

الخيار shell الموجود في التابع child_process.spawn()‎ غير مدعوم في التابع child_process.fork()‎ وسيُتجاهل إن مرِّر إليه.

child_process.spawn(command[, args][, options])‎

سجل التغييرات
الإصدار التغييرات
v8.8.0 أضيف الخيار windowsHide.
v6.4.0 أضيف الخيار argv0.
v5.7.0 أضيف الخيار shell.
v0.1.90 أضيف هذا التابع.
  • command: ‏<string> الأمر المراد تنفيذه.
  • args: ‏<string[]‎> قائمة سلاسل نصية تمثِّل الوسائط المراد استعمالها مع الأمر command.
  • options: ‏<Object> كائنٌ من النوع Object يمكن أن يحتوي على الخيارات التالية:
    • cwd: ‏<string> سلسلةٌ نصيةٌ تمثِّل مجلد العمل الحالي للعملية الابن. القيمة الافتراضيَّة هي: null.
    • env: ‏<Object> كائنٌ يتكون من الأزواج مفتاح/قيمة يمثِّل البيئة.
    • argv0: ‏<string> يضبط هذا الخيار قيمة argv[0]‎ المراد إرسالها إلى العمليَّة الابن. إن لم يُعطَ هذا المعامل، فسيُعيَّن إلى command.
    • stdio: ‏<Array> | ‏<string> يمثِّل هذا الخيار ضبط مجاري الدخل والخرج القياسية (stdio) للعملية الابن. ارجع إلى القسم «الخيار options.stdio» في الأسفل للمزيد من التفاصيل.
    • deached: ‏<boolean> قيمةٌ منطقيةٌ تحدِّد إن كانت ستعمل العمليَّة الابن بشكل مستقل عن العمليَّة الأب لها. يعتمد هذا السلوك على المنصة المستعملة (ارجع إلى القسم «الخيار options.detached» في الأسفل للمزيد من التفاصيل).
    • uid: ‏<number> عددٌ يحدِّد مُعرِّف المستخدم المالك للعملية (ارجع إلى setuid(2)‎).
    • gid: ‏<number> عددٌ يحدِّد مُعرِّف المجموعة المالكة للعملية (ارجع إلى setgid(2)‎).
    • shell: ‏<boolean> | ‏<string> إن كان true، فسيُنفَّذ الأمر command داخل صدفةٍ. ستُستعمل '‎/bin/sh' في يونكس والأنظمة الشبيهة به، و process.env.ComSpec في ويندوز، ويمكن تحديد صدفة أخرى بتمرير سلسلة نصية لهذا الخيار. ارجع إلى القسم «متطلبات الصدفة» والقسم «صدفة ويندوز الافتراضيَّة» في الأسفل للمزيد من التفاصيل. القيمة الافتراضيَّة هي: false (عدم استعمال صدفة).
    • windowsVerbatimArguments: ‏<boolean> قيمةٌ منطقيَّةٌ تحدِّد إن كان يراد اقتباس أو تهريب الوسائط في ويندوز أم لا. يُضبَط هذا الخيار إلى القيمة true تلقائيًّا عند ضبط الخيار shell. يتجاهل هذا الخيار في الأنظمة الشبيهة بيونكس. القيمة الافتراضيَّة في: false.
    • windowsHide: ‏<boolean> قيمةٌ منطقيةٌ تتحكم بإظهار وإخفاء نافذة الطرفية للعملية الفرعية التي ستظهر دومًا بشكل اعتيادي في أنظمة ويندوز. القيمة الافتراضيَّة هي: false.
  • نوع القيمة المعادة: <ChildProcess>

يولد التابع child_process.spawn()‎ عملية جديدة باستعمال الأمر command المعطى مع وسائط سطر الأوامر المحدَّدة في المعامل args. إن لم يعطَ هذا المعامل، فسيعيَّن افتراضيًّا إلى مصفوفة فارغة.

تحذير: إن مُرِّرت القيمة المنطقية true للخيار shell، فلا تمرِّر مدخلات المستخدم إلى هذه الدالة مطلقًا ما لم تتحقَّق من صحتها وسلامتها، إذ يستطيع المستخدم التحايل وإدخال محارف خاصَّة بالصدفة (metacharacters) -مثل : أو &- مما يسمح له بتشغيل أوامر أخرى.

يُستعمَل الوسيط الثالث options لتحديد خيارات إضافية مع تخصيص قيمة افتراضية لها:

const defaults = {
  cwd: undefined,
  env: process.env
};

يُستعمَل الخيار cwd لتحديد مجلد العمل الذي ستولد العمليَّة منه. إن لم يعطَ، فسيُورث مجلد العمل الحالي بشكل افتراضي.

يُستعمَل الخيار env لتحديد متغيرات البيئة التي ستكون متاحةً للعملية الجديدة. القيمة الافتراضيَّة لهذا الخيار هي process.env. انتبه إلى أنَّه سيتم تجاهل القيم undefined أينما وجدت في الخيار env.

توضِّح الشيفرة التالية مثالًا عن تنفيذ الأمر ls -lh /usr مع التحكم بمجرى الدخل القياسي، ومجرى الخطأ القياسي، وحالة الخروج:

const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

مثالٌ آخر يوضِّح بالتفصيل كيفيَّة تنفيذ الأمر ps ax | grep ssh:

const { spawn } = require('child_process');
const ps = spawn('ps', ['ax']);
const grep = spawn('grep', ['ssh']);

ps.stdout.on('data', (data) => {
  grep.stdin.write(data);
});

ps.stderr.on('data', (data) => {
  console.log(`ps stderr: ${data}`);
});

ps.on('close', (code) => {
  if (code !== 0) {
    console.log(`ps process exited with code ${code}`);
  }
  grep.stdin.end();
});

grep.stdout.on('data', (data) => {
  console.log(data.toString());
});

grep.stderr.on('data', (data) => {
  console.log(`grep stderr: ${data}`);
});

grep.on('close', (code) => {
  if (code !== 0) {
    console.log(`grep process exited with code ${code}`);
  }
});

المثال التالي يوضِّح كيفيَّة التحقُّق من فشل التابع spawn:

const { spawn } = require('child_process');
const subprocess = spawn('bad_command');

subprocess.on('error', (err) => {
  console.log('Failed to start subprocess.');
});

ستَستعمِل بعض المنصات (مثل لينكس وماك) قيمة argv[0]‎ لاسم العمليَّة بينما ستستعمل منصات أخرى (مثل ويندوز ونظام SunOS) الأمر command فقط.

في الوقت الحالي، تستبدل Node.js بقيمة argv[0]‎ القيمة process.execPath عند بدء التشغيل، لذا لن تتطابق process.argv[0]‎ في العمليَّة الابن مع قيمة المعامل argv0 المُمرَّرة إلى spawn من العمليَّة الأب بل ستعيدها مع الخاصِّيَّة process.argv0 عوضًا عن ذلك.

الخيار options.detached

أضيف في الإصدار v0.7.10.

في منصة ويندوز، يؤدي ضبط الخيار options.detached إلى القيمة true إلى توفير إمكانيَّة استمرار عمل العمليَّة الابن بعد خروج العمليَّة الأب، إذ سيكون للعملية الابن آنذاك نافذة طرفيَّة خاصَّة بها. انتبه إلى أنهَّ متى ما فُعِّل هذا الخيار للعملية الابن، لن يعطَّل بعدئذٍ.

أمَّا في بقية المنصات، إن ضُبِطَ الخيار options.detached إلى القيمة true، فستُعيِّن العمليَّة الابن قائدًا للمجموعة والجلسة الخاصَّتين بالعمليَّة الجديدة. انتبه إلى أنَّه قد تستمر العمليَّة الابن بالعمل حتى بعد خروج العمليَّة الأب بغض النظر إن كانتا مستقلتين أم لا. ارجع إلى صفحة setsid(2)‎ للمزيد من التفاصيل.

ستنتظر العمليَّة الأب بشكل افتراضي انتهاء العمليَّة الابن المستقلة. إن أردت منعها من الانتظار، فاستعمل التابع subprocess.unref()‎ الذي سيَمنع حلقة أحداث العمليَّة الأب من إضافة العمليَّة الابن مع مرجعٍ لها؛ نتيجةً لذلك، ستتمكن العمليَّة الأب التي أصبحت مستقلة عن العمليَّة الابن من الخروج متى ما أرادت ذلك ما لم يكن هنالك قناة اتصال IPC منشأةٌ بينهما.

عند استعمال الخيار detached لبدء عمليَّة تعمل لمدة طويلة، لن تستمر العمليَّة الابن بالعمل في الخلفية بعد خروج العمليَّة الأب إلا إذا توافر ضبطٌ للخيار stdio وكان هذا الضبط لا يسمح للمجرى بالاتصال بأي شكل من الأشكال مع العمليَّة الأب. إن ورثت العمليَّة الابن مجاري الدخل والخرج القياسية (stdio) من العمليَّة الأب، فستبقى العمليَّة الابن مستقلةً بالتحكم بالطرفية.

تحوي الشيفرة التالية مثالًا عن عملية ابن طويلة الأمد، إذ يُفصَل ويُتجاهَل واصف ملف مجاري الدخل والخرج القياسية (stdio) للعملية الأب لها من أجل تجاهل انتهاء وخروج العمليَّة الأب:

const { spawn } = require('child_process');

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore'
});

subprocess.unref();

بدلًا من ذلك، يمكن إعادة توجيه مخرجات العمليات الأبناء إلى ملفات خارجية:

const fs = require('fs');
const { spawn } = require('child_process');
const out = fs.openSync('./out.log', 'a');
const err = fs.openSync('./out.log', 'a');

const subprocess = spawn('prg', [], {
  detached: true,
  stdio: [ 'ignore', out, err ]
});

subprocess.unref();

الخيار options.stdio

الإصدار التغييرات
v3.3.1 أصبحت القيمة 0 مقبولة باستعمالها كواصف ملفٍ.
0.7.10 أضيف هذا الخيار.

يستعمل الخيار options.stdio لضبط الأنابيب المنشأة بين العمليَّة الأب والعمليَّة الابن. يعاد توجيه مجاري الخرج والدخل والخطأ القياسية للعمليَّة الابن إلى المجاري options.stdio، و options.stdout، و options.stderr المقابلة في الكائن ChildProcess. يكافئ هذا ضبط الخيار options.stdio مثلًا إلى القيمة ['pipe', 'pipe', 'pipe'].

لتحقيق التوافقية، يمكن أن يكون الخيار options.stdio إحدى السلاسل النصية التالية:

  • 'pipe': وهذا يكافئ ['pipe', 'pipe', 'pipe'] وهي القيمة الافتراضيَّة، أو
  • 'ignore': وهذا يكافئ ['ignore', 'ignore', 'ignore']، أو
  • 'inherit': وهذا يكافئ [process.stdin, process.stdout, process.stderr] أو [0,1,2].

خلا ذلك، ستكون قيمة الخيار options.stdio مصفوفةً يقابل فهرس كل عنصر فيها واصف ملفٍ (file descriptor، أو fd اختصارًا) في العمليَّة الابن. فتقابل مثلًا واصفات الملفات 0، و 1، و 2 مجرى الخرج القياسي، ومجرى الدخل القياسي، ومجرى الخطأ القياسي على التوالي. يمكن تحديد واصفات ملفات إضافيَّة لإنشاء أنابيب إضافية بين العمليَّة الأب والعلمية الابن.

يمكن استعمال إحدى القيم التالية مع الخيار options.stdio:

  1. 'pipe': إنشاء أنبوب بين العمليَّة الابن والعمليَّة الأب. تكون نهاية الأنبوب من طرف العمليَّة الأب مرئيةً للعملية الأب كخاصِّيَّة في الكائن child_process مثل القيمة subprocess.stdio[fd]‎. الأنابيب المنشأة من أجل واصفات الملفات 0، و 1، و 2 متاحةً أيضًا بوصفها subprocess.stdin، و subprocess.stdout، و subprocess.stderr على التوالي.
  2. 'ipc': إنشاء قناة IPC لتمرير رسائل أو واصفات ملف بين العلمية الأب والعمليَّة الابن. قد يملك الكائن ChildProcess قناة IPC واحدة لواصف ملف مجاري الدخل والخرج القياسية (stdio) على الأكثر. يؤدي ضبط هذا الخيار إلى تفعيل التابع subprocess.send()‎. إن كانت العمليَّة الابن هي عملية Node.js، فسيُفعِّل وجود القناة IPC التابعين process.send()‎ و process.disconnect()‎ بالإضافة إلى الحدثين 'disconnect' و 'message' ضمن العمليَّة الابن. لا يمكن الوصول إلى واصف ملف القناة IPC بأيِّ طريقة كانت غير process.send()‎ أو استعمال القناة IPC مع عملية ابنٍ ليست نسخةً من Node.js.
  3. 'ignore': حثُّ Node.js على تجاهل واصف الملف في العمليَّة الابن. لمَّا كانت Node.js تفتح واصفات من 0 إلى 2 للعمليات التي تولدها، فسيؤدي ضبط واصف الملف إلى القيمة 'ignore' إلى إجبار Node.js على فتح ‎/dev/null وربطه بواصف ملف العمليَّة الابن.
  4. كائن stream: ‏<Stream> مشاركة مجرى قابل للقراءة أو للكتابة يشير إلى وحدة tty أو ملفٍ، أو مقبسٍ، أو أنبوبٍ مع العمليَّة الابن. يضاعف واصف الملف المضمِّن للمجرى في العمليَّة الابن إلى الواصف المقابل لفهرس المصفوفة stdio. انتبه إلى أنَّه يجب أن يكون للمجرى واصف مُضمَّن (لا ينطبق هذا على مجاري الملفات حتى يقع الحدث 'open').
  5. عددٌ صحيح موجب: تفسير القيمة العددية على أنَّها واصف ملف مفتوح حاليًا في العمليَّة الأب وتمت مشاركته مع العمليَّة الابن، بطريقة مشابهة لمشاركة الكائنات stream.
  6. القيمة null، والقيمة undefined: استعمال القيم الافتراضيَّة. سيُنشأ أنبوبٌ من أجل واصفات ملف مجاري الدخل والخرج القياسية (stdio) وهي 0، و 1، و 2 (أي مجرى الدخل القياسي (stdio)، ومجرى الخرج القياسي (stdout)، ومجرى الخطأ القياسي (stderr)). أمَّا من أجل واصف الملف 3 وما بعده، فالقيمة الافتراضيَّة له هي 'ignore'.

إليك المثال التالي الذي يشرح ما سبق:

const { spawn } = require('child_process');

// ستستعمل العمليَّة الابن مجاري الدخل والخرج القياسية الخاصة بالعمليَّة الأب
spawn('prg', [], { stdio: 'inherit' });

// ستشارك العمليَّة الابن المولدة مجرى الخطأ القياسي فقط
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });

// startd-style للتفاعل مع برامج تعرض الواجهة fd=4 فتح مجرى إضافي عبر
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });

الجدير بالذكر أنَّه عند إنشاء قناة IPC بين العمليات الآباء والعمليات الأبناء وكانت العمليَّة الابن إحدى عمليات Node.js، فستبدأ العمليَّة الابن مع قناة IPC غير مرجعيَّة (باستعمال unref()‎) حتى تُعيِّن هذه العمليَّة الابن معالج حدثٍ من أجل الحدث 'disconnect' أو الحدث 'message'. يسمح ذلك للعملية الابن بالخروج بشكل طبيعي دون الإبقاء على هذه العمليَّة مفتوحةً من طرف القناة IPC المفتوحة.

في الأنظمة الشبيهة بيونكس، يُجرِي التابع child_process.spawn()‎ بعض العمليات على الذاكرة بشكل متزامن قبل فصل حلقة الأحداث (event loop) من العمليَّة الابن. قد تجد التطبيقات التي تحجز جزءًا كبيرًأ من الذاكرة استدعاءات متكررة وعالقة للتابع child_process.spawn()‎. للمزيد من التفاصيل، راجع المشكلة 7381.

انظر أيضًا التابع child_process.exec()‎، والتابع child_process.fork()‎.

إنشاء عملية متزامنة

التوابع child_process.spawnSync()‎، و child_process.execSync()‎، و child_process.execFileSync()‎ هي توابع متزامنة، وستَحجِب حلقة الأحداث (event loop) مانعةً بذلك من تنفيذ أي جزءٍ آخرٍ من الشيفرة ريثمَّا تنتهي العمليَّة المولدة.

حجب الاستدعاءات في مثل هذه الحالة له فائدة جمَّة في تبسيط مهام السكربتات ذات الغرض العام (general-purpose scripting tasks) و تبسيط تحميل أو معالجة إعدادات التطبيقات عند بدء تشغيلها.

child_process.execFileSync(file[, args][, options])‎

سجل التغييرات
الإصدار التغييرات
v8.8.0 إضافة المعامل windowsHide.
v8.0.0 أصبح بالإمكان استعمال الكائن Uint8Array مع المعامل input.
v6.2.1 - v4.5.0 أصبح بالإمكان ضبط قيمة الخيار encoding إلى buffer.
v0.11.12 أضيف هذا التابع.
  • file: ‏<string> سلسلةٌ نصيةٌ تحوي اسم أو مسار الملف القابل للتنفيذ المراد تشغيله.
  • args: ‏<string[]‎> قائمةٌ من سلاسل نصية تمثل الوسائط المراد استعمالها مع الملف file.
  • options: ‏<Object> كائنٌ من النوع Object يمكن أن يحتوي على الخيارات التالية:
    • cwd: ‏<string> سلسلةٌ نصيةٌ تمثِّل مجلد العمل الحالي للعملية الابن. القيمة الافتراضيَّة هي: null.
    • input: ‏<string> | ‏<Buffer> | ‏<Uint8Array> القيم التي ستُمرَّر إلى العمليَّة المولدة كمجرى دخل وخرج قياسي. إعطاء قيمة لهذا المعامل سيؤدي إلى تجاهل stdio[0]‎.
    • stdio: ‏<Array> | ‏<string> يمثِّل هذا المعامل الضبط المخصَّص لمجاري الدخل والخرج القياسية للعملية الابن. سيُستعمَل مجرى الخطأ القياسي للعملية نفس مجرى الخطأ القياسي للعملية الأب ما لم يُعطَ هذا المعامل. القيمة الافتراضيَّة هي: 'pipe'.
    • env: ‏<Object> كائنٌ يتكون من الأزواج مفتاح/قيمة يمثِّل البيئة.
    • uid: ‏<number> عددٌ يحدِّد مُعرِّف المستخدم المالك للعملية (ارجع إلى setuid(2)‎).
    • gid: ‏<number> عددٌ يحدِّد مُعرِّف المجموعة المالكة للعملية (ارجع إلى setgid(2)‎).
    • timeout: ‏<number> الفترة الزمنية القصوى بالميلي ثانية التي يسمح فيها للعملية بالعمل. القيمة الافتراضيَّة هي: undefined.
    • killSignal: ‏<string> | ‏<integer> قيمة الإشارة المراد استعمالها عندما يتم قتل (kill) العمليَّة المولدة. القيمة الافتراضيَّة هي: 'SIGTERM'.
    • maxBuffer: ‏<number> عددٌ يمثِّل أكبر حجم مسموحٍ به للبيانات بالبايت في مجرى الخرج والخطأ القياسيين. في حال تجاوز هذه القيمة، ستُنهَى العمليَّة الابن مباشرةً. ارجع إلى القسم «الخيار maxBuffer والترميز الموحد». القيمة الافتراضيَّة هي: 200 * 1024.
    • encoding: ‏<string> سلسلةٌ نصية تمثل الترميز المراد استعماله مع جميع مدخلات ومخرجات مجاري الدخل والخرج القياسية. القيمة الافتراضيَّة هي: 'buffer'.
    • windowsHide: ‏<boolean> قيمةٌ منطقيةٌ تتحكم بإظهار وإخفاء نافذة الطرفية للعملية الفرعية التي ستُنشأ دومًا بشكل اعتيادي في أنظمة ويندوز. القيمة الافتراضيَّة هي: false.
    • shell‏ <boolean>‏ | ‏<string> إن كانت true، فسيُنفَّذ الأمر command داخل صدفةٍ. ستستعمل '‎/bin/sh' في يونكس والأنظمة الشبيهة به، و process.env.ComSpec في ويندوز، ويمكن تحديد صدفة أخرى بتمرير سلسلة نصية لهذا الخيار. ارجع إلى القسم «متطلبات الصدفة» والقسم «صدفة ويندوز الافتراضيَّة» في الأسفل للمزيد من التفاصيل. القيمة الافتراضيَّة هي: false (عدم استعمال صدفة).
  • القيم المعادة: <Buffer> |‏ <string> مجرى الخرج القياسي من الأمر.

يشبه هذا التابعُ التابعَ child_process.execFile()‎ في جميع النواحي عمومًا باستثناء أنه لن يعيد أي شيء حتى تغلق العمليَّة الابن بشكل كامل. عندما تنتهي المهلة الزمنية (timeout) وترسل الإشارة killSignal، فلن تعيد هذه الدالة أي شيء حتى خروج العمليَّة كاملًا.

إن اعترضت العمليَّة الابن الإشارة SIGTERM وعالجتها ولم تخرج، فستبقى العمليَّة الأب منتظرةً حتى خروج تلك العمليَّة.

إن انتهت مهلة العمليَّة الابن أو خرجت بحالة خروج مغايرة للصفر، فسيَرمي هذا التابع خطأً يتضمن نتيجة استدعاء التابع child_process.spawnSync()‎ ضمنيًا كاملةً.

تحذير: إن مُرِّرت القيمة المنطقيَّة true للخيار shell، فلا تمرِّر مدخلات المستخدم إلى هذه الدالة مطلقًا ما لم تتحقَّق من صحتها وسلامتها، إذ يستطيع المستخدم التحايل وإدخال محارف خاصَّة بالصدفة (metacharacters) -مثل : أو &- مما يسمح له بتشغيل أوامر أخرى.

child_process.execSync(command[, options])‎

سجل التغييرات
الإصدار التغييرات
v8.8.0 إضافة المعامل windowsHide.
v8.0.0 أصبح بالإمكان استعمال الكائن Uint8Array مع المعامل input.
v0.11.12 أضيف هذا التابع.
  • command: ‏<string> سلسلةٌ نصيةٌ تحوي الأمر المراد تنفيذه.
  • args:‏ <string[]‎> قائمةٌ من سلاسل نصية تمثل الوسائط المراد استعمال مع الأمر command.
  • options:‏ <Object> كائنٌ من النوع Object يمكن أن يحتوي على الخيارات التالية:
    • cwd: ‏<string> سلسلةٌ نصيةٌ تمثِّل مجلد العمل الحالي للعملية الابن. القيمة الافتراضيَّة هي: null.
    • input: ‏<string> | ‏<Buffer> | ‏<Uint8Array> القيم التي ستُمرَّر إلى العمليَّة المولدة كمجرى دخل وخرج قياسي. إعطاء قيمة لهذا المعامل سيؤدي إلى تجاهل stdio[0].
    • stdio:‏ <Array> | ‏<string> يمثِّل هذا المعامل الضبط المخصَّص لمجاري الدخل والخرج القياسية للعملية الابن. سيستعمل مجرى الخطأ القياسي للعملية الابن نفس مجرى الخطأ القياسي للعملية الأب ما لم يعطَ هذا المعامل. القيمة الافتراضيَّة هي: 'pipe'.
    • env: ‏<Object> كائنٌ يتكون من الأزواج مفتاح/قيمة يمثِّل البيئة.
    • shell: ‏<string> الصدفة المراد تنفيذ الأمر command داخلها. ارجع إلى القسم «متطلبات الصدفة» والقسم «صدفة ويندوز الافتراضيَّة» في الأسفل للمزيد من التفاصيل. القيمة الافتراضيَّة هي: '‎/bin/sh' في يونكس والأنظمة الشبيهة به، و process.env.ComSpec في ويندوز.
    • uid: ‏<number> عددٌ يحدِّد مُعرِّف المستخدم المالك للعملية (ارجع إلى setuid(2)‎).
    • gid: ‏<number> عددٌ يحدِّد مُعرِّف المجموعة المالكة للعملية (ارجع إلى setgid(2)‎).
    • timeout:‏ <number> الفترة الزمنية القصوى بالميلي ثاينة التي يُسمَح فيها للعملية بالعمل. القيمة الافتراضيَّة هي: undefined.
    • killSignal: ‏<string> | ‏<integer> قيمة الإشارة المراد استعمالها عندما يتم قتل (kill) العمليَّة المولدة. القيمة الافتراضيَّة هي: 'SIGTERM'.
    • maxBuffer: ‏<number> عددٌ يمثِّل أكبر حجم مسموحٍ به للبيانات بالبايت في مجرى الخرج والخطأ القياسيين. في حال تجاوز هذه القيمة، ستُنهَى العمليَّة الابن مباشرةً. ارجع إلى القسم «الخيار maxBuffer والترميز الموحد». القيمة الافتراضيَّة هي: 200 * 1024.
    • encoding: ‏<string> سلسلةٌ نصيةٌ تمثِّل الترميز المراد استعماله مع جميع مدخلات ومخرجات مجاري الدخل والخرج القياسية. القيمة الافتراضيَّة هي: 'buffer'.
    • windowsHide: ‏<boolean> قيمةٌ منطقيةٌ تتحكم بإظهار وإخفاء نافذة الطرفية للعملية الفرعية التي ستُنشأ دومًا بشكل اعتيادي في أنظمة ويندوز. القيمة الافتراضيَّة هي: false.
  • القيم المعادة: <Buffer> | ‏<string> مجرى الخرج القياسي من الأمر.

يشبه هذا التابعُ التابعَ child_process.exec()‎ في جميع النواحي عمومًا باستثناء أنَّه لن يعيد أي شيء حتى تُغلق العمليَّة الابن بشكل كامل. فعندما تنتهي المهلة الزمنية (timeout) وتُرسَل الإشارة killSignal، لن تعيد هذه الدالة أي شيء حتى خروج العمليَّة كاملًا.

انتبه إلى أنه إذا اعترضت العمليَّة الابن الإشارة SIGTERM وعالجتها ولم تخرج، فستبقى العمليَّة الأب منتظرةً حتى خروج تلك العمليَّة.

إن انتهت مهلة العمليَّة الابن أو خرجت بحالة خروج مغايرة للصفر، فسيَرمي هذا التابع خطأً يتضمن نتيجة استدعاء التابع child_process.spawnSync()‎ ضمنيًا كاملةً.

تحذير: إن مُرِّرت القيمة المنطقيَّة true للخيار shell، فلا تمرِّر مدخلات المستخدم إلى هذه الدالة مطلقًا ما لم تتحقَّق من صحتها وسلامتها، إذ يستطيع المستخدم التحايل وإدخال محارف خاصَّة بالصدفة (metacharacters) -مثل : أو &- مما يسمح له بتشغيل أوامر أخرى.

child_process.spawnSync(command[, args][, options])‎

سجل التغييرات
الإصدار التغييرات
v8.8.0 أضيف المعامل windowsHide.
v8.0.0 أصبح بالإمكان استعمال الكائن Uint8Array مع المعامل input.
v6.2.1 - v4.5.0 أصبح بالإمكان ضبط قيمة الخيار encoding الآن إلى buffer.
v5.7.0 أضيف المعامل shell.
v0.11.12 أضيف هذا التابع.
  • command:‏ <string> سلسلةٌ نصيةٌ تحوي الأمر المراد تنفيذه.
  • args:‏ <string[]‎> قائمةٌ من سلاسل نصية تمثل الوسائط المراد استعمال مع الأمر command.
  • options:‏ <Object> كائنٌ من النوع Object يمكن أن يحتوي على الخيارات التالية:
    • cwd: ‏<string> سلسلةٌ نصيةٌ تمثِّل مجلد العمل الحالي للعملية الابن. القيمة الافتراضيَّة هي: null.
    • input:‏ <string> | ‏<Buffer> | ‏<Uint8Array> القيم التي ستُمرَّر إلى العمليَّة المولدة كمجرى دخل وخرج قياسي. إعطاء قيمة لهذا المعامل سيؤدي إلى تجاهل stdio[0]‎.
    • stdio: ‏<Array> | ‏<string> يمثِّل هذا المعامل الضبط المخصص لمجاري الدخل والخرج القياسية للعملية الابن.
    • env: ‏<Object> كائنٌ يتكون من الأزواج مفتاح/قيمة يمثِّل البيئة.
    • uid: ‏<number> عددٌ يحدِّد مُعرِّف المستخدم المالك للعملية (ارجع إلى setuid(2)‎).
    • gid: ‏<number> عددٌ يحدِّد مُعرِّف المجموعة المالكة للعملية (ارجع إلى setgid(2)‎).
    • timeout:‏ <number> الفترة الزمنية القصوى بالميلي ثاينة التي يُسمح فيها للعملية بالعمل. القيمة الافتراضيَّة هي: undefined.
    • killSignal:‏ <string> | ‏<integer> قيمة الإشارة المراد استعمالها عندما يتم قتل (kill) العمليَّة المولدة. القيمة الافتراضيَّة هي: 'SIGTERM'.
    • maxBuffer: ‏<number> عددٌ يمثِّل أكبر حجم مسموحٍ به للبيانات بالبايت في مجرى الخرج والخطأ القياسيين. في حال تجاوز هذه القيمة، ستُنهَى العمليَّة الابن مباشرةً. ارجع إلى القسم «الخيار maxBuffer والترميز الموحد». القيمة الافتراضيَّة هي: 200 * 1024.
    • encoding: ‏<string> سلسلةٌ نصيةٌ تمثِّل الترميز المراد استعماله مع جميع مدخلات ومخرجات مجاري الدخل والخرج القياسية. القيمة الافتراضيَّة هي: 'buffer'.
    • shell:‏ <boolean> | ‏<string> إن كانت true، فسيُنفَّذ الأمر command داخل صدفةٍ. ستستعمل '‎/bin/sh' في يونكس والأنظمة الشبيهة به، و process.env.ComSpec في ويندوز، ويمكن تحديد صدفة أخرى بتمرير سلسلة نصية لهذا الخيار. ارجع إلى القسم «متطلبات الصدفة» والقسم «صدفة ويندوز الافتراضيَّة» في الأسفل للمزيد من التفاصيل. القيمة الافتراضيَّة هي: false (عدم استعمال صدفة).
    • windowsVerbatimArguments:‏ <boolean> قيمةٌ منطقيَّةٌ تحدِّد إن كان يراد اقتباس أو تهريب الوسائط في ويندوز أم لا. يُتجاهل هذا الخيار في الأنظمة الشبيهة بيونكس. القيمة الافتراضيَّة في: false.
    • windowsHide: ‏<boolean> قيمةٌ منطقيَّةٌ تتحكم بإظهار وإخفاء نافذة الطرفية للعملية الفرعية التي ستُنشأ دومًا بشكل اعتيادي في أنظمة ويندوز. القيمة الافتراضيَّة هي: false.
  • القيم المعادة: <Object>
    • pid: ‏<number> عددٌ يمثِّل مُعرِِّف العمليَّة الابن.
    • output: ‏<Array> مصفوفةٌ تحوي نتائج مخرجات مجاري الدخل والخرج القياسية.
    • stdout: ‏<Buffer> | ‏<string> محتوى المجرى output[1]‎.
    • stderr: ‏<Buffer> | ‏<string> محتوى المجرى output[2]‎.
    • status: ‏<number> حالة خروج العمليَّة الابن.
    • signal: ‏<string> الإشارة المستعملة في قتل العمليَّة الابن.
    • error: ‏<Error> الكائن errer إن فشلت العمليَّة الابن أو انتهت مهلتها الزمنية.

يشبه هذا التابعُ التابعَ child_process.spawn()‎ في جميع النواحي عمومًا باستثناء أنَّه لن يعيد أي شيء حتى تُغلَق العمليَّة الابن بشكل كامل. فعندما تنتهي المهلة الزمنية (timeout) وتُرسَل الإشارة killSignal، لن تعيد هذه الدالة أي شيء حتى خروج العمليَّة كاملًا.

انتبه إلى أنَّه إذا اعترضت العمليَّة الابن الإشارة SIGTERM وعالجتها ولم تخرج، فستبقى العمليَّة الأب منتظرةً حتى خروج تلك العمليَّة.

إن انتهت مهلة العمليَّة الابن أو خرجت بحالة خروج مغايرة للصفر، فسيَرمي هذا التابع خطأً يتضمن نتيجة استدعاء التابع child_process.spawnSync()‎ ضمنيًا كاملةً.

تحذير: إن مُرِّرت القيمة المنطقيَّة true للخيار shell، فلا تمرِّر مدخلات المستخدم إلى هذه الدالة مطلقًا ما لم تتحقَّق من صحتها وسلامتها، إذ يستطيع المستخدم التحايل وإدخال محارف خاصَّة بالصدفة (metacharacters) -مثل : أو &- مما يسمح له بتشغيل أوامر أخرى.

الصنف ChildProcess

أضيف في الإصدار v2.2.0.

النُسَخ المنشأة من الصنف ChildProcess هي EventEmitters التي تمثل العمليات المُولَّدة.

لا تُنشَأ النسخ ChildProcess بشكل مباشر بل تستعمل التوابع child_process.spawn()‎، أو child_process.exec()‎، أو child_process.execFile()‎، أو child_process.fork()‎ لإنشائها.

الحدث 'close'

أضيف في الإصدار v0.7.7.

  • code: ‏<number> حالة الخروج إن خرجت العمليَّة بمفردها.
  • signal: ‏<string> الإشارة التي استُعملت لإنهاء العمليَّة الابن.

يُطلق الحدث 'close' عند إغلاق مجاري الدخل والخرج القياسية للعملية الابن. يختلف هذا الحدث عن الحدث 'exit'، إذ قد تتشارك عدَّة عمليات مجاري الخرج والدخل القياسية نفسها.

الحدث 'disconnect'

أضيف في الإصدار v0.7.2.

يُطلق الحدث 'disconnect' بعد استدعاء التابع subprocess.disconnect()‎ في العمليَّة الأب أو التابع process.disconnect()‎ في العمليَّة الابن. بعد قطع الاتصال بين العمليَّة الأب والابن، لن يعد بالإمكان إرسال أو استقبال أية رسائل بينهما، وستصبح قيمة الخاصِّيَّة subprocess.connected القيمة false.

الحدث 'error'

يُطلق الحدث 'error' في حال:

  1. لم يكن بالإمكان توليد العمليَّة، أو
  2. لم يكن بالإمكان قتل العمليَّة، أو
  3. فشلُ إرسال رسالةٍ إلى العمليَّة الابن.

قد يُطلق الحدث 'exit' أو لا بعد حدوث خطأٍ. عند الاستماع إلى الحدثين 'exit' و 'error' كلاهما، من المهم ضمان عدم استدعاء دوال معالجة الحدث عدة مرات من غير قصد.

انظر أيضًا التابع subprocess.kill()‎ والتابع subprocess.send()‎.

الحدث 'exit'

أضيف في الإصدار v0.1.90.

  • code: ‏<number> حالة الخروج إن خرجت العمليَّة بمفردها.
  • signal: ‏<string> الإشارة التي استُعملت لإنهاء العمليَّة الابن.

يُطلق الحدث بعد انتهاء العمليَّة الابن. إن خرجت العمليَّة، سيحوي code نسخةً من حالة الخروج النهائية لتلك العمليَّة. خلا ذلك، ستكون قيمته null. أمَّا إن أُنهيت العمليَّة نتيجة تلقيها إشارة معيَّنة، فسيحوي signal اسم تلك الإشارة. خلا ذلك، ستكون قيمته null.

انتبه إلى أنَّه عندما يُطلق الحدث 'exit'، ربما لا تزال مجاري الخرج والدخل للعمليَّة الابن مفتوحةً آنذاك.

انتبه أيضًا إلى أنَّ Node.js تنشئ معالجات إشارة (signal handlers) من أجل الإشارة SIGINI والإشارة SIGTRM، ولن تتوقف عمليات Node.js مباشرةً عندما تتلقى هاتين الإشارتين. عوضًا عن ذلك، ستُجري Node.js سلسلةً من أعمال التنظيف ثمَّ ستعيد عرض الإشارة المعالجة.

انظر أيضًا الدالة waitpid(2)‎.

الحدث 'message'

أضيف في الإصدار v0.5.9.

  • mesage: ‏<Object> كائن JSON مفسَّر أو قيمة أولية.
  • sendHandle: ‏<Handle> كائن net.Socket، أو كائن net.Server، أو قيمة غير مُعرَّفة.

يُطلق الحدث 'message' عندما تُستعمَل العمليَّة الابن التابع process.send(0)‎ لإرسال رسائل.

تمرُّ الرسائل المرسلة عبر عمليات ترميز (serialization) وتفسير (parsing)، لذا لن تشبه الرسالة المستلمة في أغلب الأحيان الرسالة الأصلية المرسلة.

الخاصِّيَّة subprocess.connected

أضيفت في الإصدار v0.7.2.

  • <boolean> تضبط إلى القيمة false بعد استدعاء التابع subprocess.disconnect()‎.

تحدد الخاصِّيَّة subprocess.connected إن لا يزال بالإمكان إرسال واستقبال رسائل من وإلى العمليَّة الابن. عندما تصبح قيمة الخاصِّيَّة false، لن نتمكن بعدئذٍ من إرسال أو استلام أية رسالة.

التابع subprocess.disconnect()‎

أضيف في الإصدار V0.7.2.

يغلق هذا التابع القناة IPC بين العمليَّة الأب والعمليَّة الابن عند استدعائه، مما يسمح بخروج العمليَّة الابن بأمان متى ما انقطعت الاتصالات التي كانت تبقيها تعمل. بعد استدعاء هذا التابع، ستُضبط قيمة الخاصِّيَّة subprocess.connected والخاصِّيَّة process.connected في العمليَّة الأب والابن كلاهما (على التوالي) إلى القيمة false. نتئجةً لذلك، لن يعد بالإمكان تمرير أية رسالة بين هاتين العمليتين.

سيُطلق الحدث 'disconnect' عندما لا يكون هنالك أية رسائل في العمليَّة المستقبِلة. سيُطلق هذا الحدث في أغلب الأحيان بعد استدعاء subprocess.disconnect()‎ مباشرةً.

انتبه إلى أنَّه عندما تكون العمليَّة نسخةً من Node.js (مثل توليد عملية باستعمال child_process.fork()‎)، فيمكن استدعاء التابع process.disconnect()‎ ضمن العمليَّة الابن لإغلاق القناة IPC أيضًا.

subprocess.kill([signal])‎

أضيف في الإصدار v0.1.90.

  • signal:‏ <string> الإشارة المراد إرسالها إلى العمليَّة الابن. القيمة الافتراضيَّة هي: 'SIGTERM'.

يرسل هذا التابع إشارةً إلى العمليَّة الابن. إن لم يعطَ أي وسيط، فسيرسل التابع الإشارة 'SIGTERM' إلى العمليَّة. ارجع إلى الدالة signal(7)‎ للاطلاع على قائمة الإشارات المتاحة.

const { spawn } = require('child_process');
const grep = spawn('grep', ['ssh']);

grep.on('close', (code, signal) => {
  console.log(
    `child process terminated due to receipt of signal ${signal}`);
});

// إلى العمليَّة SIGHUP إرسال الإشارة
grep.kill('SIGHUP');

يمكن أن يطلِق الكائن ChildProcess الحدث 'error' إن لم تُسلَّم الإشارة المرسلة للعملية. فإرسال إشارة إلى عملية ابن قد أغلقت للتو ليس خطأً ولكن قد يترتَّب على ذلك عواقب غير متوقعة. على وجه التحديد، إن أعيد إسناد مُعرِّف العمليَّة (PID) إلى عملية أخرى، فستُسلَّم الإشارة إلى هذه العمليَّة بدلًا من العمليَّة المقصودة، وسنحصل بذلك على نتائج لا يحمد عقباها.

انتبه إلى أنَّه لما كان اسم الدالة «kill» يشير إلى «قتل» العمليَّة، فليس بالضرورة أن تكون الإشارة المرسلة إلى العمليَّة الابن إشارة إنهاءٍ لتلك العمليَّة.

انظر أيضًا الدالة kill(2)‎.

انتبه أيضًا أنه في لينكس، لن توقف العمليات الأبناء للعمليات الأبناء عند محاول قتل العمليَّة الأب لها. يرجَّح أن يحدث هذا عند تشغيل عملية جديدة في صدفةٍ أو مع استعمال الخيار shell للكائن ChildProcess. توضِّح الشيفرة التالية هذا الأمر:

'use strict';
const { spawn } = require('child_process');

const subprocess = spawn(
  'sh',
  [
    '-c',
    `node -e "setInterval(() => {
      console.log(process.pid, 'is alive')
    }, 500);"`
  ], {
    stdio: ['inherit', 'inherit', 'inherit']
  }
);

setTimeout(() => {
  subprocess.kill(); // التي تعمل في الصدفة node لا تُنهِي العمليَّة
}, 2000);

الخاصِّيَّة subprocess.killed

أضيف في الإصدار v0.5.10.

  • <boolean> تُضبَط إلى القيمة بعد استعمال التابع subprocess.kill()‎ من أجل إرسال إشارةٍ إلى العمليَّة الابن بنجاح.

تحدِّد الخاصِّيَّة subprocess.killed إن كانت العمليَّة الابن قد استَلمت بنجاح إشارةً من التابع subprocess.kill()‎، إذ لا تشير هذه الخاصِّيَّة إن كانت قد أُنهيت العمليَّة الابن أم لا.

الخاصِّيَّة subprocess.pid

أضيفت في الإصدار v0.1.90.

تعيد هذه الخاصِّيَّة مُعرِّف العمليَّة (PID) للعملية الابن.

const { spawn } = require('child_process');
const grep = spawn('grep', ['ssh']);

console.log(`Spawned child pid: ${grep.pid}`);
grep.stdin.end();

subprocess.send(message[, sendHandle[, options]][, callback])‎

سجل التغييرات
الإصدار التغييرات
v5.8.0 أضيف المعامل option والخيار keepOpen تحديدًا.
v5.0.0 أصبحت هذه الدالة تعيد قيمة منطقية للتحكم بالتدفق الآن.
v4.0.0 أضيف المعامل callback.
v0.5.9 أضيف هذا التابع.
  • message: ‏<Object>
  • sendHandle: ‏<Handle>
  • options: ‏<Object> كائنٌ يُستعمل لضبط عمليَّة إرسال أنواع محدَّدة من المعالجات. يدعم هذا الكائن الخاصِّيَّات التالية:
    • keepOpen: ‏<boolean> يُستعمَل هذا الخيار عند تمرير نُسخٍ من net.Socket. عندما تكون true، سيُبقى على المقبس مفتوحًا خلال عمليَّة الإرسال. القيمة الافتراضيَّة هي: false.
  • callback: ‏<Function>
  • نوع القيم المعادة: <boolean>

عندما تُنشَأ قناة IPC بين العمليَّة الأب والعمليَّة الابن (مثل عند استعمال التابع child_process.fork()‎)، يمكن حينئذٍ استعمال التابع subprocess.send()‎ لإرسال رسائل إلى العمليَّة الابن. وعندما تكون العمليَّة الابن هي نسخةٌ من Node.js، فيمكن استلام هذه الرسائل عبر الحدث 'message'.

تخضع الرسالة خلال إرسالها من المرسل إلى المستقبل إلى عمليَّة ترميز وتفسير، لذا لن تشبه في أغلب الأحيان الرسالة المستلمة الرسالة الأصلية نفسها التي أرسلت.

تفحَّص مثلًا الشيفرة التالية التي تعود إلى عملية أب:

const cp = require('child_process');
const n = cp.fork(`${__dirname}/sub.js`);

n.on('message', (m) => {
  console.log(الأب استلم رسالة:', m);
});

// {يجب أن نجعل العمليَّة الابن تطبع الرسالة التالية: الابن استلم رسالة: {مرحبًا أيها العالم
n.send({ مرحبًا أيها العالم });

وستكون الشيفرة الخاصَّة بالعمليَّة الابن شبيهةً بالشيفرة التالية:

process.on('message', (m) => {
  console.log(الابن استلم رسالة:', m);
});

// {NaN :يجب أن نجعل العمليَّة الأب تطبع الرسالة التالية: الأب استلم رسالة: {{تفاح: 'موجود', موز
process.send({ تفاح: 'موجود موز: NaN});

لدى عمليات Node.js الابن تابعٌ خاص بها لإرسال رسائل إلى العمليَّة الأب ألا وهو التابع process.send()‎.

هنالك حالة خاصَّة تتعلق بإرسال رسالة تشبه {cmd: 'NODE_foo'‎}، إذ إن للبادئة NODE_‎ معنًى خاص عند احتواء الخاصِّيَّة cmd عليها  واستعمالها ضمن نواة Node.js، ولن تظهر في الحدث 'message' للعملية الابن. عوضًا عن ذلك، نجد مثل هذه الرسائل في الحدث 'internalMessage'، إذ تحفظها Node.js داخليًا. يجب على التطبيقات تجنب استعمال مثل هذه الرسائل أو استعمال أحداث مثل 'internalMessage' التي تتغير دون أي تنبيه بذلك.

يُستعمَل الخيار sendHandle المُمرَّر إلى التابع subprocess.send()‎ في تمرير الكائن TCP server أو الكائن socket إلى العمليَّة الابن. سيُستلم الابن الكائن كأنَّه وسيط ثانٍ مُرِّر إلى دالة رد النداء المسجلة في الحدث 'message'. أية بيانات تُستَلم وتُخزَّن في المقبس ستُرسل إلى العمليَّة الابن.

يمثِّل المعامل callback الاختياري دالةً تستدعى عد إتمام إرسال الرسالة وغالبًا قبل أن تستلم العمليَّة الابن هذا الرسالة.  تستدعى هذه الدالة مع وسيط وحيد؛ يكون هذا الوسيط القيمة null عند نجاح عملية الإرسال، أو الكائن Error عند فشلها.

إن لم يعطَ المعامل callback ولم يُتمكن من إرسال الرسالة، فسيُطلِق الكائن ChildProcess الحدث 'error'. يحدث هذا مثلًا عندما تكون العمليَّة الابن قد أُغلقَت مسبقًا.

سيعيد التابع subprocess.send()‎ القيمة المنطقية false إن أغلقت القناة أو عندما تتجاوز الرسائل غير المرسلة المتراكمة حدًا يصبح فيه من غير المعقول إرسال المزيد من الرسائل. خلا ذلك، سيعيد التابع القيمة true. يمكن أيضًا استعمال الدالة callback للتحكم بتدفق البيانات ضمن القناة.

مثالٌ عن إرسال الكائن server

يمكن استعمال المعامل sendHandle لتمرير معالج الكائن TCP server مثلًا إلى العمليَّة الابن كما هو موضح في المثال التالي:

const subprocess = require('child_process').fork('subprocess.js');

// وإرسال المعالج server فتح الكائن
const server = require('net').createServer();
server.on('connection', (socket) => {
  socket.end('handled by parent');
});
server.listen(1337, () => {
  subprocess.send('server', server);
});

ستستلم الآن العمليَّة الابن الكائن server بالشكل التالي:

process.on('message', (m, server) => {
  if (m === 'server') {
    server.on('connection', (socket) => {
      socket.end('handled by child');
    });
  }
});

حالما يصبح الخادم مشاركًا بين العمليَّة الأب والأبن، يمكن معالجة بعض الاتصالات عبر العمليَّة الأب وبعضها الآخر عبر العمليَّة الابن.

لمَّا كان هذا المثال يستعمل خادمًا أنشئ باستعمال الوحدة net، فإنَّ خوادم الوحدة dgram تستعمل نفس سير العمل تمامًا باستثناء الاستماع إلى الحدث 'message' بدلًأ من الحدث 'connection' واستعمال التابع server.bind()‎ بدلًا من التابع server.listen()‎. على أي حال، هذا مدعوم حاليًا في المنصات الشبيهة بيونكس فقط.

مثالٌ عن إرسال الكائن socket

بطريقةٍ مشابهةٍ للمثال السابق، يمكن استعمال المعامل sendHandle لتمرير معالج الكائن socket إلى العمليَّة الابن. في الشيفرة التالية، سيتولد عمليتي ابن تعالج كلٌّ منهما الاتصالات ذات الأولوية «طبيعي» (normal) أو «استثنائي» (special):

const { fork } = require('child_process');
const normal = fork('subprocess.js', ['normal']);
const special = fork('subprocess.js', ['special']);

// لمنع pauseOnConnect فتح الخادم ثمَّ إرسال المقابس إلى العمليَّة الابن. سيُستعمل الخيار 
// قراءة المقابس قبل إرسالها إلى العمليَّة الابن
const server = require('net').createServer({ pauseOnConnect: true });
server.on('connection', (socket) => {

  // إن كان هذا الاتصال ذو أولوية طبيعية
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket);
    return;
  }
  // وإن كان هذا الاتصال ذو أولية استثنائية
  normal.send('socket', socket);
});
server.listen(1337);

ستستلم الخاصِّيَّة subprocess.js المعالج socket كوسيط ثانٍ مُرِّر إلى دالة رد نداء الحدث:

process.on('message', (m, socket) => {
  if (m === 'socket') {
    if (socket) {
      // .التحقق من خروج مقبس العميل
      // .يحتمل أن يكون المقبس مغلقًا في فترة الإرسال والاستقبال في العمليَّة الابن
      socket.end(`Request handled with ${process.argv[2]} priority`);
    }
  }
});

حالما يُمرَّر مقبسٌ إللى العمليَّة الابن، لن يعد بإمكان العمليَّة الأب تتبع متى يُدمَّر المقبس. لمعرفة ذلك، تصبح قيمة الخاصِّيَّة ‎.connections بعد تدميرالمقبس null. لا ينصح باستعمال الخاصِّيَّة ‎.maxConnections عندما يحدث ذلك.

ينصح أيضًا بالتأكد من أيَّة معالجات للحدث 'message' في العمليَّة الابن حيث يوجد الكائن socket، إذ قد يُغلق الاتصال في الوقت الذي تستغرقه العمليَّة في إرسال الاتصال إلى العمليَّة الابن.

الخاصية subprocess.stderr

أضيفت في الإصدار v0.1.90.

  • <stream.Readable>

تعدُّ هذه الخاصِّيَّة مجرًى قابلًا للقراءة  يمثِّل مجرى الخطأ القياسي (stderr) للعملية الابن.

إن ولِّدت العمليَّة الابن مع ضبط قيمة الخيار stdio[2]‎ إلى أية قيمة باستثناء 'pipe'، فستكون حينئذٍ قيمة هذه الخاصِّيَّة null.

هذه الخاصِّيَّة هي اسمٌ بديل للخاصِّيَّة subprocess.stdio[2]‎، وستشير كلا الخاصِّيَّتين إلى القيمة نفسها.

الخاصية subprocess.stdin

أضيفت في الإصدار v0.1.90.

  • <stream.Writable>

تعدُّ هذه الخاصِّيَّة مجرًى قابلًا للكتابة يمثِّل مجرى الدخل القياسي (stdin) للعملية الابن.

انتبه إلى أنَّه إن انتظرت العمليَّة الابن حتى تُقرأ جميع المدخلات الخاصَّة بها، فلن تَستأنف عملها حتى يُغلق هذا المجرى عبر استدعاء end()‎.

إن ولِّدت العمليَّة الابن مع ضبط قيمة الخيار stdio[0]‎ إلى أيَّة قيمة باستثناء 'pipe'، فستكون حينئذٍ قيمة هذه الخاصِّيَّة null.

هذه الخاصِّيَّة هي اسمٌ بديل للخاصِّيَّة subprocess.stdio[0]‎، وستشير كلا الخاصِّيَّتين إلى القيمة نفسها.

الخاصية subprocess.stdio

أضيفت في الإصدار v0.7.10.

تمثِّل هذه الخاصِّيَّة مصفوفةً من الأنابيب المتفرقة المتصلة بالعمليَّة الابن، وتتطابق مع موقع القيمة 'pipe' المعطاة في الخيار stdio المُمرَّر إلى التابع child_process.spawn()‎. انتبه إلى أنَّ التوابع subprocess.stdio[0]‎، و  subprocess.stdio[1]‎، و subprocess.stdio[2]‎ متاحةً أيضًا بالشكل subprocess.stdin، و subprocess.stdout، و subprocess.stderr على التوالي.

في المثال التالي، يُضبَط واصف الملف 1 (stdout) للعملية الابن إلى القيمة 'pipe'، لذا يتشكل لدينا المجرى subprocess.stdio[1]‎ فقط في العمليَّة الأب، وستأخذ جميع قيم المصفوفة الأخرى القيمة null:

const assert = require('assert');
const fs = require('fs');
const child_process = require('child_process');

const subprocess = child_process.spawn('ls', {
  stdio: [
    0, // Use parent's stdin for child
    'pipe', // Pipe child's stdout to parent
    fs.openSync('err.out', 'w') // توجيه مجرى الخطأ القياسي للعملية الابن إلى ملف
  ]
});

assert.strictEqual(subprocess.stdio[0], null);
assert.strictEqual(subprocess.stdio[0], subprocess.stdin);

assert(subprocess.stdout);
assert.strictEqual(subprocess.stdio[1], subprocess.stdout);

assert.strictEqual(subprocess.stdio[2], null);
assert.strictEqual(subprocess.stdio[2], subprocess.stderr);

الخاصية subprocess.stdout

أضيفت في الإصدار v0.1.90.

  • <stream.Readable>

تعدُّ هذه الخاصِّيَّة مجرًى قابلًا للقراءة يمثِّل مجرى الخرج القياسي (stdout) للعملية الابن.

إن ولِّدت العمليَّة الابن مع ضبط قيمة الخيار stdio[1]‎ إلى أيَّة قيمة باستثناء 'pipe'، فستكون حينئذٍ قيمة هذه الخاصِّيَّة null.

هذه الخاصِّيَّة هي اسمٌ بديل للخاصِّيَّة subprocess.stdio[1]‎، وستشير كلا الخاصِّيَّتين إلى القيمة نفسها.

الخيار maxBuffer والترميز الموحد (Unicode)

يحدِّد الخيار maxBuffer أكبر عددٍ من البايتات المسموح نقلها عبر مجريي الخرج والخطأ القياسيين. في تجاوزت عدد البايتات هذه القيمة، فستُنهى العمليَّة الابن. إنَّ لهذا تأثير على المخرجات التي تحوي ترميزًا لمحارف متعدِّدة البايتات مثل الترميز UTF-8 أو UTF-16. على سبيل المثال، سيُرسِل console.log('中文测试')‎ ثلاثة عشر بايتًا مُرمَّزة بترميز UTF-8 إلى مجرى الخرج القياسي رغم أنَّ الرسالة تحوي أربعة محارف فقط.

متطلبات الصدفة

يجب أن تتعرَّف الصدفة على المبدل ‎-c في الأنظمة الشبيهة بيونكس أو ‎/d /s /c  في أنظمة ويندوز. في ويندوز، يجب أن يكون مفسِّر سطر الأوامر متوافقًا مع 'cmd.exe'.

صدفة ويندوز الافتراضية

رغم أنَّ مايكروسوفت قد خصَّصت %COMSPEC% ليحتوي على مسار 'cmd.exe' في البيئة الجذرية (root environment) إلا أنَّ العمليات الأبناء لا تخضع دومًا إلى المتطلبات نفسها. نتيجةً لذلك، تستخدم 'cmd.exe' في الدوال child_process حيث بالإمكان توليد صدفةٍ كحل بديل إن كانت process.env.ComSpec غير متاحة.

مصادر