عملية فرعية
[مستقر: 2 - مستقر]
مستقر: 2 استقرار: 2 - مستقر
المصدر: lib/child_process.js
يوفر مُعامل node:child_process
القدرة على إنشاء عمليات فرعية بطريقة مشابهة، ولكنها ليست مطابقة، لـ popen(3)
. يتم توفير هذه القدرة بشكل أساسي بواسطة دالة child_process.spawn()
:
const { spawn } = require('node:child_process')
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.stderr.on('data', data => {
console.error(`stderr: ${data}`)
})
ls.on('close', code => {
console.log(`child process exited with code ${code}`)
})
import { spawn } = from 'node:child_process';
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
بشكل افتراضي، يتم إنشاء أنابيب لـ stdin
و stdout
و stderr
بين عملية Node.js الأصلية والعملية الفرعية التي تم إنشاؤها. تتمتع هذه الأنابيب بسعة محدودة (ومحددة بنظام التشغيل). إذا كتبت العملية الفرعية إلى stdout أكثر من هذه الحد دون التقاط الإخراج، فإن العملية الفرعية تتوقف في انتظار أن يقبل مخزن الأنابيب المزيد من البيانات. هذا مطابق لسلوك الأنابيب في shell. استخدم خيار { stdio: 'ignore' }
إذا لم يتم استهلاك الإخراج.
يتم البحث عن الأمر باستخدام متغير البيئة options.env.PATH
إذا كان env
موجودًا في كائن options
. خلاف ذلك، يتم استخدام process.env.PATH
. إذا تم تعيين options.env
بدون PATH
، فسيتم إجراء البحث في Unix على مسار بحث افتراضي /usr/bin:/bin
(راجع دليل نظام التشغيل الخاص بك لمعرفة execvpe/execvp)، وفي Windows، يتم استخدام متغير بيئة العمليات الحالية PATH
.
في Windows، تكون متغيرات البيئة غير حساسة لحالة الأحرف. تقوم Node.js بفرز مفاتيح env
أبجدياً وتستخدم أول مفتاح يطابق حالة الأحرف. سيتم تمرير الإدخال الأول فقط (بالترتيب الأبجدي) إلى العملية الفرعية. قد يؤدي هذا إلى مشاكل في Windows عند تمرير كائنات إلى خيار env
يحتوي على العديد من المتغيرات لنفس المفتاح، مثل PATH
و Path
.
تقوم طريقة child_process.spawn()
بإنشاء العملية الفرعية بشكل غير متزامن، دون حظر حلقة أحداث Node.js. توفر دالة child_process.spawnSync()
وظائف مكافئة بطريقة متزامنة تحظر حلقة الأحداث حتى تخرج العملية التي تم إنشاؤها أو يتم إنهاؤها.
للتسهيل، يوفر مُعامل node:child_process
عددًا قليلاً من البدائل المتزامنة وغير المتزامنة لـ child_process.spawn()
و child_process.spawnSync()
. يتم تنفيذ كل من هذه البدائل فوق child_process.spawn()
أو child_process.spawnSync()
.
child_process.exec()
: ينشئ shell ويشغل أمرًا داخل ذلك shell، ويمررstdout
وstderr
إلى دالة callback عند اكتمال العملية.child_process.execFile()
: مشابه لـchild_process.exec()
إلا أنه ينشئ الأمر مباشرة دون إنشاء shell أولاً بشكل افتراضي.child_process.fork()
: ينشئ عملية Node.js جديدة ويدعو وحدة محددة مع قناة اتصال IPC تم إنشاؤها تسمح بإرسال الرسائل بين الأصل والفرع.child_process.execSync()
: إصدار متزامن منchild_process.exec()
سيحظر حلقة أحداث Node.js.child_process.execFileSync()
: إصدار متزامن منchild_process.execFile()
سيحظر حلقة أحداث Node.js.
بالنسبة لبعض حالات الاستخدام، مثل أتمتة نصوص shell، قد تكون النظائر المتزامنة أكثر ملاءمة. ومع ذلك، في كثير من الحالات، قد يكون للطرق المتزامنة تأثير كبير على الأداء بسبب توقف حلقة الأحداث أثناء اكتمال العمليات التي تم إنشاؤها.
إنشاء عمليات غير متزامنة
تتبع كل من طرق child_process.spawn()
و child_process.fork()
و child_process.exec()
و child_process.execFile()
نمط البرمجة غير المتزامن الأصلي النموذجي لواجهات برمجة التطبيقات الأخرى في Node.js.
كل طريقة من هذه الطرق تُرجع مثيلًا من ChildProcess
. تُنفذ هذه الكائنات واجهة برمجة التطبيقات EventEmitter
الخاصة بـ Node.js، مما يسمح لعملية الأب بتسجيل دوال المُستمع التي يتم استدعاؤها عند حدوث أحداث معينة خلال دورة حياة عملية الطفل.
بالإضافة إلى ذلك، تسمح كل من الطريقتين child_process.exec()
و child_process.execFile()
بتحديد دالة callback
اختيارية يتم استدعاؤها عند إنهاء عملية الطفل.
إنشاء ملفات .bat
و .cmd
على Windows
قد يختلف مدى أهمية التمييز بين child_process.exec()
و child_process.execFile()
باختلاف النظام الأساسي. على أنظمة التشغيل من نوع Unix (Unix و Linux و macOS)، قد تكون child_process.execFile()
أكثر كفاءة لأنها لا تُنشئ قشرة افتراضيًا. ومع ذلك، على نظام التشغيل Windows، لا يمكن تنفيذ ملفات .bat
و .cmd
بمفردها بدون محطة، وبالتالي لا يمكن تشغيلها باستخدام child_process.execFile()
. عند التشغيل على نظام التشغيل Windows، يمكن استدعاء ملفات .bat
و .cmd
باستخدام child_process.spawn()
مع تعيين خيار shell
، أو باستخدام child_process.exec()
، أو عن طريق إنشاء cmd.exe
ومرور ملف .bat
أو .cmd
كوسيطة (وهذا ما يفعله خيار shell
و child_process.exec()
). في أي حال، إذا كان اسم الملف النصي يحتوي على مسافات، فيجب وضع علامات اقتباس حوله.
// أو...
const { exec, spawn } = require('node:child_process')
exec('my.bat', (err, stdout, stderr) => {
if (err) {
console.error(err)
return
}
console.log(stdout)
})
// نص برمجي به مسافات في اسم الملف:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true })
// أو:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
// ...
})
// أو...
import { exec, spawn } from 'node:child_process'
exec('my.bat', (err, stdout, stderr) => {
if (err) {
console.error(err)
return
}
console.log(stdout)
})
// نص برمجي به مسافات في اسم الملف:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true })
// أو:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
// ...
})
child_process.exec(command[, options][, callback])
[History]
الإصدار | التغييرات |
---|---|
v15.4.0 | تمت إضافة دعم AbortSignal. |
v16.4.0، v14.18.0 | يمكن أن يكون خيار cwd كائن WHATWG URL باستخدام بروتوكول file: . |
v8.8.0 | أصبح خيار windowsHide مدعومًا الآن. |
v0.1.90 | تمت الإضافة في: v0.1.90 |
command
<string> الأمر الذي سيتم تشغيله، مع الوسائط مفصولة بمسافات.options
<Object>cwd
<string> | <URL> دليل العمل الحالي لعملية الطفل. الافتراضي:process.cwd()
.env
<Object> أزواج القيمة الرئيسية للبيئة. الافتراضي:process.env
.encoding
<string> الافتراضي:'utf8'
shell
<string> قشرة لتشغيل الأمر بها. راجع متطلبات القشرة و قشرة Windows الافتراضية. الافتراضي:'/bin/sh'
على يونكس،process.env.ComSpec
على Windows.signal
<AbortSignal> يسمح بإلغاء عملية الطفل باستخدام AbortSignal.timeout
<number> الافتراضي:0
maxBuffer
<number> أكبر قدر من البيانات بالبايت مسموح به على stdout أو stderr. إذا تم تجاوزه، فسيتم إنهاء عملية الطفل ويتم اقتطاع أي إخراج. راجع التحذير فيmaxBuffer
و Unicode. الافتراضي:1024 * 1024
.killSignal
<string> | <integer> الافتراضي:'SIGTERM'
uid
<number> يحدد هوية المستخدم للعملية (انظرsetuid(2)
).gid
<number> يحدد هوية المجموعة للعملية (انظرsetgid(2)
).windowsHide
<boolean> إخفاء نافذة وحدة التحكم الفرعية التي سيتم إنشاؤها عادةً على أنظمة Windows. الافتراضي:false
.
callback
<Function> يتم استدعاؤه مع الإخراج عند إنهاء العملية.الإرجاع: <ChildProcess>
يولد قشرة ثم ينفذ command
داخل تلك القشرة، ويعمل على تخزين أي إخراج تم إنشاؤه. يتم معالجة سلسلة command
الممررة إلى دالة exec مباشرةً بواسطة القشرة، وتحتاج الأحرف الخاصة (تختلف بناءً على القشرة) إلى التعامل معها وفقًا لذلك:
const { exec } = require('node:child_process')
exec('"/path/to/test file/test.sh" arg1 arg2')
// يتم استخدام علامات اقتباس مزدوجة حتى لا يتم تفسير المسافة في المسار كـ
// فاصل بين وسيطات متعددة.
exec('echo "The \\$HOME variable is $HOME"')
// يتم تجنب متغير $HOME في المثال الأول، ولكن ليس في الثاني.
import { exec } from 'node:child_process'
exec('"/path/to/test file/test.sh" arg1 arg2')
// يتم استخدام علامات اقتباس مزدوجة حتى لا يتم تفسير المسافة في المسار كـ
// فاصل بين وسيطات متعددة.
exec('echo "The \\$HOME variable is $HOME"')
// يتم تجنب متغير $HOME في المثال الأول، ولكن ليس في الثاني.
لا تقم أبدًا بنقل إدخال المستخدم غير المعقم إلى هذه الوظيفة. يمكن استخدام أي إدخال يحتوي على أحرف خاصة بالقشرة لتنشيط تنفيذ الأمر التعسفي.
إذا تم توفير دالة callback
، فسيتم استدعاؤها باستخدام الوسائط (error, stdout, stderr)
. في حالة النجاح، ستكون error
هي null
. في حالة حدوث خطأ، ستكون error
مثيلًا لـ Error
. ستكون خاصية error.code
هي رمز الخروج للعملية. باتفاقية، يشير أي رمز خروج بخلاف 0
إلى خطأ. ستكون error.signal
هي الإشارة التي أنهت العملية.
ستحتوي الوسائط stdout
و stderr
الممررة إلى دالة callback على إخراج stdout و stderr لعملية الطفل. بشكل افتراضي، سيقوم Node.js بفك تشفير الإخراج كـ UTF-8 ويمرر السلاسل إلى دالة callback. يمكن استخدام خيار encoding
لتحديد ترميز الأحرف المستخدم لفك تشفير إخراج stdout و stderr. إذا كان encoding
هو 'buffer'
، أو ترميز أحرف غير معروف، فسيتم تمرير كائنات Buffer
إلى دالة callback بدلاً من ذلك.
const { exec } = require('node: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.error(`stderr: ${stderr}`)
})
import { exec } from 'node: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.error(`stderr: ${stderr}`)
})
إذا كانت قيمة timeout
أكبر من 0
، فسترسل عملية الأب الإشارة التي تم تحديدها بواسطة خاصية killSignal
(الافتراضي هو 'SIGTERM'
) إذا استغرقت عملية الطفل وقتًا أطول من timeout
ميلي ثانية.
على عكس مكالمة النظام POSIX exec(3)
، لا يحل child_process.exec()
محل العملية الحالية ويستخدم قشرة لتنفيذ الأمر.
إذا تم استدعاء هذه الطريقة كنسختها المُحسّنة بـ util.promisify()
، فإنها تُرجع Promise
لكائن يحتوي على خصائص stdout
و stderr
. يتم إرفاق مثيل ChildProcess
المُرجع إلى Promise
كخاصية child
. في حالة حدوث خطأ (بما في ذلك أي خطأ ينتج عنه رمز خروج بخلاف 0)، يتم إرجاع وعد مُرفوض، بنفس كائن error
المُعطى في دالة callback، ولكن مع خاصيتين إضافيتين هما stdout
و stderr
.
const util = require('node:util')
const exec = util.promisify(require('node:child_process').exec)
async function lsExample() {
const { stdout, stderr } = await exec('ls')
console.log('stdout:', stdout)
console.error('stderr:', stderr)
}
lsExample()
import { promisify } from 'node:util'
import child_process from 'node:child_process'
const exec = promisify(child_process.exec)
async function lsExample() {
const { stdout, stderr } = await exec('ls')
console.log('stdout:', stdout)
console.error('stderr:', stderr)
}
lsExample()
إذا تم تمكين خيار signal
، فإن استدعاء .abort()
على AbortController
المقابل يشبه استدعاء .kill()
على عملية الطفل باستثناء أن الخطأ الممرر إلى دالة callback سيكون AbortError
:
const { exec } = require('node:child_process')
const controller = new AbortController()
const { signal } = controller
const child = exec('grep ssh', { signal }, error => {
console.error(error) // an AbortError
})
controller.abort()
import { exec } from 'node:child_process'
const controller = new AbortController()
const { signal } = controller
const child = exec('grep ssh', { signal }, error => {
console.error(error) // an AbortError
})
controller.abort()
child_process.execFile(file[, args][, options][, callback])
[History]
الإصدار | التغييرات |
---|---|
v16.4.0, v14.18.0 | يمكن أن يكون خيار cwd كائن WHATWG URL باستخدام بروتوكول file: . |
v15.4.0, v14.17.0 | تمت إضافة دعم AbortSignal. |
v8.8.0 | يُدعم خيار windowsHide الآن. |
v0.1.91 | تمت الإضافة في: v0.1.91 |
file
<string> اسم أو مسار ملف التنفيذ الذي سيتم تشغيله.args
<string[]> قائمة بحجج السلسلة.options
<Object>cwd
<string> | <URL> دليل العمل الحالي لعملية الطفل.env
<Object> أزواج المفتاح والقيمة للبيئة. الافتراضي:process.env
.encoding
<string> الافتراضي:'utf8'
timeout
<number> الافتراضي:0
maxBuffer
<number> أكبر قدر من البيانات بالبايت مسموح به على stdout أو stderr. إذا تجاوز الحد، فسيتم إنهاء عملية الطفل ويتم اقتطاع أي إخراج. راجع التحذير فيmaxBuffer
and Unicode. الافتراضي:1024 * 1024
.killSignal
<string> | <integer> الافتراضي:'SIGTERM'
uid
<number> يحدد هوية المستخدم للعملية (انظرsetuid(2)
).gid
<number> يحدد هوية المجموعة للعملية (انظرsetgid(2)
).windowsHide
<boolean> إخفاء نافذة وحدة التحكم الفرعية التي سيتم إنشاؤها عادةً على أنظمة Windows. الافتراضي:false
.windowsVerbatimArguments
<boolean> لا يتم وضع علامات اقتباس أو الهروب للحجج على Windows. يتم تجاهلها على Unix. الافتراضي:false
.shell
<boolean> | <string> إذا كانtrue
، فإنه يقوم بتشغيلcommand
داخل shell. يستخدم'/bin/sh'
على Unix، وprocess.env.ComSpec
على Windows. يمكن تحديد shell مختلف كسلسلة. راجع متطلبات Shell و Shell Windows الافتراضي. الافتراضي:false
(بدون shell).signal
<AbortSignal> يسمح بإلغاء عملية الطفل باستخدام AbortSignal.
callback
<Function> يتم استدعاؤه مع الإخراج عند إنهاء العملية.الإرجاع: <ChildProcess>
تُشبه دالة child_process.execFile()
دالة child_process.exec()
إلا أنها لا تقوم بإنشاء shell افتراضيًا. بدلاً من ذلك، يتم إنشاء ملف التنفيذ المحدد file
مباشرةً كعملية جديدة مما يجعلها أكثر كفاءة قليلاً من child_process.exec()
.
يتم دعم نفس الخيارات مثل child_process.exec()
. نظرًا لعدم إنشاء shell، لا يتم دعم السلوكيات مثل إعادة توجيه I/O وفرز الملفات.
const { execFile } = require('node:child_process')
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
if (error) {
throw error
}
console.log(stdout)
})
import { execFile } from 'node:child_process'
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
if (error) {
throw error
}
console.log(stdout)
})
ستحتوي حجج stdout
و stderr
الممررة إلى callback على إخراج stdout و stderr لعملية الطفل. بشكل افتراضي، سيقوم Node.js بفك تشفير الإخراج كـ UTF-8 ويمرر السلاسل إلى callback. يمكن استخدام خيار encoding
لتحديد ترميز الأحرف المستخدم لفك تشفير إخراج stdout و stderr. إذا كان encoding
هو 'buffer'
، أو ترميز أحرف غير معروف، فسيتم تمرير كائنات Buffer
إلى callback بدلاً من ذلك.
إذا تم استدعاء هذه الطريقة كنسختها util.promisify()
، فإنها تُرجع Promise
لكائن يحتوي على خصائص stdout
و stderr
. يتم إرفاق مثيل ChildProcess
المُرجع إلى Promise
كخاصية child
. في حالة حدوث خطأ (بما في ذلك أي خطأ ينتج عنه رمز خروج بخلاف 0)، يتم إرجاع وعد مُرفوض، بنفس كائن error
المعطى في callback، ولكن مع خاصيتين إضافيتين هما stdout
و stderr
.
const util = require('node:util')
const execFile = util.promisify(require('node:child_process').execFile)
async function getVersion() {
const { stdout } = await execFile('node', ['--version'])
console.log(stdout)
}
getVersion()
import { promisify } from 'node:util'
import child_process from 'node:child_process'
const execFile = promisify(child_process.execFile)
async function getVersion() {
const { stdout } = await execFile('node', ['--version'])
console.log(stdout)
}
getVersion()
إذا تم تمكين خيار shell
، فلا تقم بتمرير إدخال غير معقم من المستخدم إلى هذه الدالة. يمكن استخدام أي إدخال يحتوي على أحرف معدنية shell لتنشيط تنفيذ الأوامر التعسفي.
إذا تم تمكين خيار signal
، فإن استدعاء .abort()
على AbortController
المقابل يشبه استدعاء .kill()
على عملية الطفل باستثناء أن الخطأ الممرر إلى callback سيكون AbortError
:
const { execFile } = require('node:child_process')
const controller = new AbortController()
const { signal } = controller
const child = execFile('node', ['--version'], { signal }, error => {
console.error(error) // an AbortError
})
controller.abort()
import { execFile } from 'node:child_process'
const controller = new AbortController()
const { signal } = controller
const child = execFile('node', ['--version'], { signal }, error => {
console.error(error) // an AbortError
})
controller.abort()
child_process.fork(modulePath[, args][, options])
[السجل]
الإصدار | التغييرات |
---|---|
v17.4.0، v16.14.0 | يمكن أن يكون مُعامل modulePath كائن URL من WHATWG باستخدام بروتوكول file: |
v16.4.0، v14.18.0 | يمكن أن يكون خيار cwd كائن URL من WHATWG باستخدام بروتوكول file: |
v15.13.0، v14.18.0 | تمت إضافة timeout . |
v15.11.0، v14.18.0 | تمت إضافة killSignal لـ AbortSignal . |
v15.6.0، v14.17.0 | تمت إضافة دعم AbortSignal . |
v13.2.0، v12.16.0 | أصبح خيار serialization مدعومًا الآن. |
v8.0.0 | يمكن أن يكون خيار stdio الآن سلسلة. |
v6.4.0 | أصبح خيار stdio مدعومًا الآن. |
v0.5.0 | تمت الإضافة في: v0.5.0 |
modulePath
<سلسلة> | <URL> الوحدة المُراد تشغيلها في العملية الفرعية.args
<مصفوفة من السلاسل> قائمة من وسيطات السلسلة.options
<كائن>cwd
<سلسلة> | <URL> دليل العمل الحالي لعملية الطفل.detached
<قيمة منطقية> تحضير عملية الطفل لتشغيلها بشكل مستقل عن عملية الوالد. يعتمد السلوك المحدد على النظام الأساسي، انظرoptions.detached
).env
<كائن> أزواج قيمة المفتاح للبيئة. الافتراضي:process.env
.execPath
<سلسلة> القابل للتنفيذ المستخدم لإنشاء عملية الطفل.execArgv
<مصفوفة من السلاسل> قائمة من وسيطات السلسلة المُمررة إلى القابل للتنفيذ. الافتراضي:process.execArgv
.gid
<رقم> يُعيّن هوية المجموعة للعملية (انظرsetgid(2)
).serialization
<سلسلة> تحديد نوع التسلسل المستخدم لإرسال الرسائل بين العمليات. القيم الممكنة هي'json'
و'advanced'
. راجع التسلسل المتقدم لمزيد من التفاصيل. الافتراضي:'json'
.signal
<AbortSignal> يسمح بإغلاق عملية الطفل باستخدامAbortSignal
.killSignal
<سلسلة> | <عدد صحيح> قيمة الإشارة التي سيتم استخدامها عند قتل العملية التي تم إنشاؤها بواسطة مهلة زمنية أو إشارة إيقاف. الافتراضي:'SIGTERM'
.silent
<قيمة منطقية> إذا كانتtrue
، فسيتم توصيل stdin و stdout و stderr لعملية الطفل بعملية الوالد، وإلا فسيتم وراثتها من عملية الوالد، راجع خيارات'pipe'
و'inherit'
لـchild_process.spawn()
'sstdio
لمزيد من التفاصيل. الافتراضي:false
.stdio
<مصفوفة> | <سلسلة> انظرchild_process.spawn()
'sstdio
. عند توفير هذا الخيار، فإنه يتجاوزsilent
. إذا تم استخدام متغير المصفوفة، فيجب أن يحتوي على عنصر واحد فقط بقيمة'ipc'
أو سيتم إرجاع خطأ. على سبيل المثال[0، 1، 2، 'ipc']
.uid
<رقم> يُعيّن هوية المستخدم للعملية (انظرsetuid(2)
).windowsVerbatimArguments
<قيمة منطقية> لا يتم وضع علامات اقتباس أو إفلات الوسائط على Windows. يتم تجاهلها على Unix. الافتراضي:false
.timeout
<رقم> بالميلي ثانية الحد الأقصى لوقت السماح بتشغيل العملية. الافتراضي:undefined
.
القيمة المُرجعة: <ChildProcess>
طريقة child_process.fork()
هي حالة خاصة من child_process.spawn()
تُستخدم خصيصًا لإنشاء عمليات Node.js جديدة. مثل child_process.spawn()
، يتم إرجاع كائن ChildProcess
. سيكون لـ ChildProcess
المُرجعة قناة اتصال إضافية مُدمجة تسمح بمرور الرسائل ذهابًا وإيابًا بين الوالد والطفل. راجع subprocess.send()
للحصول على التفاصيل.
ضع في اعتبارك أن عمليات Node.js الفرعية المُنشأة مستقلة عن الوالد باستثناء قناة اتصال IPC التي تم إنشاؤها بين الاثنين. كل عملية لها ذاكرتها الخاصة، مع مثيلات V8 الخاصة بها. نظرًا لتخصيصات الموارد الإضافية المطلوبة، لا يُنصح بإنشاء عدد كبير من عمليات Node.js الفرعية.
بشكل افتراضي، سيقوم child_process.fork()
بإنشاء مثيلات Node.js الجديدة باستخدام process.execPath
لعملية الوالد. يسمح مُعامل execPath
في كائن options
باستخدام مسار تنفيذ بديل.
ستتواصل عمليات Node.js التي تم إطلاقها باستخدام execPath
مخصص مع عملية الوالد باستخدام مُعرّف مُصفف الوصف (fd) المُحدد باستخدام متغير البيئة NODE_CHANNEL_FD
في عملية الطفل.
على عكس مُكالمة نظام POSIX fork(2)
، لا يقوم child_process.fork()
باستنساخ العملية الحالية.
لا يدعم child_process.fork()
خيار shell
المتوفر في child_process.spawn()
وسيتم تجاهله إذا تم تعيينه.
إذا تم تمكين خيار signal
، فإن الاتصال بـ .abort()
على AbortController
المقابل مشابه للاتصال بـ .kill()
على عملية الطفل باستثناء أن الخطأ المُمرر إلى المُستدعى سيكون AbortError
:
const { fork } = require('node:child_process')
const process = require('node:process')
if (process.argv[2] === 'child') {
setTimeout(() => {
console.log(`Hello from ${process.argv[2]}!`)
}, 1_000)
} else {
const controller = new AbortController()
const { signal } = controller
const child = fork(__filename, ['child'], { signal })
child.on('error', err => {
// سيتم استدعاء هذا مع err كونه AbortError إذا قام المُتحكم بالإلغاء
})
controller.abort() // يُوقف عملية الطفل
}
import { fork } from 'node:child_process'
import process from 'node:process'
if (process.argv[2] === 'child') {
setTimeout(() => {
console.log(`Hello from ${process.argv[2]}!`)
}, 1_000)
} else {
const controller = new AbortController()
const { signal } = controller
const child = fork(import.meta.url, ['child'], { signal })
child.on('error', err => {
// سيتم استدعاء هذا مع err كونه AbortError إذا قام المُتحكم بالإلغاء
})
controller.abort() // يُوقف عملية الطفل
}
child_process.spawn(command[, args][, options])
[History]
الإصدار | التغييرات |
---|---|
v16.4.0، v14.18.0 | يمكن أن يكون خيار cwd كائن WHATWG URL باستخدام بروتوكول file: |
v15.13.0، v14.18.0 | تمت إضافة مهلة timeout. |
v15.11.0، v14.18.0 | تمت إضافة killSignal لإشارة الإلغاء AbortSignal. |
v15.5.0، v14.17.0 | تمت إضافة دعم إشارة الإلغاء AbortSignal. |
v13.2.0، v12.16.0 | يُدعم خيار serialization الآن. |
v8.8.0 | يُدعم خيار windowsHide الآن. |
v6.4.0 | يُدعم خيار argv0 الآن. |
v5.7.0 | يُدعم خيار shell الآن. |
v0.1.90 | تمت الإضافة في: v0.1.90 |
command
<string> الأمر الذي سيتم تشغيله.args
<string[]> قائمة بحجج السلسلة.options
<Object>cwd
<string> | <URL> دليل العمل الحالي لعملية الطفل.env
<Object> أزواج المفتاح والقيمة للبيئة. افتراضي:process.env
.argv0
<string> تعيين قيمةargv[0]
بشكل صريح المرسلة إلى عملية الطفل. سيتم تعيين هذا علىcommand
إذا لم يتم تحديده.stdio
<Array> | <string> تكوين stdio للطفل (انظرoptions.stdio
).detached
<boolean> إعداد عملية الطفل لتشغيلها بشكل مستقل عن عملية الوالد. يعتمد السلوك المحدد على النظام الأساسي، انظرoptions.detached
).uid
<number> تعيين هوية المستخدم للعملية (انظرsetuid(2)
).gid
<number> تعيين هوية المجموعة للعملية (انظرsetgid(2)
).serialization
<string> تحديد نوع التسلسل المستخدم لإرسال الرسائل بين العمليات. القيم الممكنة هي'json'
و'advanced'
. راجع التسلسل المتقدم لمزيد من التفاصيل. افتراضي:'json'
.shell
<boolean> | <string> إذا كانtrue
، فإنه يقوم بتشغيلcommand
داخل غلاف. يستخدم'/bin/sh'
على Unix، وprocess.env.ComSpec
على Windows. يمكن تحديد غلاف مختلف كسلسلة. راجع متطلبات الغلاف و غلاف Windows الافتراضي. افتراضي:false
(بدون غلاف).windowsVerbatimArguments
<boolean> لا يتم وضع علامات اقتباس أو تهرب الحجج على Windows. يتم تجاهله على Unix. يتم تعيين هذا علىtrue
تلقائيًا عند تحديدshell
وهو CMD. افتراضي:false
.windowsHide
<boolean> إخفاء نافذة وحدة التحكم الفرعية التي سيتم إنشاؤها عادةً على أنظمة Windows. افتراضي:false
.signal
<AbortSignal> يسمح بإلغاء عملية الطفل باستخدام إشارة إلغاء AbortSignal.timeout
<number> بالميلي ثانية الحد الأقصى للوقت المسموح به لعملية التشغيل. افتراضي:undefined
.killSignal
<string> | <integer> قيمة الإشارة التي سيتم استخدامها عند قتل العملية التي تم إنشاؤها بواسطة مهلة أو إشارة إلغاء. افتراضي:'SIGTERM'
.
الإرجاع: <ChildProcess>
يقوم أسلوب child_process.spawn()
بإنشاء عملية جديدة باستخدام command
المعطى، مع حجج سطر الأوامر في args
. إذا تم حذفه، فإن args
يكون افتراضيًا مصفوفة فارغة.
إذا تم تمكين خيار shell
، فلا تمرر إدخال المستخدم غير المعقم لهذه الوظيفة. يمكن استخدام أي إدخال يحتوي على أحرف ميتا قشرة لتشغيل أوامر تعسفية.
يمكن استخدام وسيطة ثالثة لتحديد خيارات إضافية، مع هذه القيم الافتراضية:
const defaults = {
cwd: undefined,
env: process.env,
}
استخدم cwd
لتحديد دليل العمل الذي يتم إنشاء العملية منه. إذا لم يتم إعطاؤه، فإن الافتراضي هو توريث دليل العمل الحالي. إذا تم إعطاؤه، ولكن المسار غير موجود، فإن عملية الطفل تُصدر خطأ ENOENT
وتخرج على الفور. يتم أيضًا إصدار ENOENT
عندما لا يوجد الأمر.
استخدم env
لتحديد متغيرات البيئة التي ستكون مرئية لعملية جديدة، والافتراضي هو process.env
.
سيتم تجاهل القيم undefined
في env
.
مثال على تشغيل ls -lh /usr
، والتقاط stdout
، و stderr
، ورمز الخروج:
const { spawn } = require('node:child_process')
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.stderr.on('data', data => {
console.error(`stderr: ${data}`)
})
ls.on('close', code => {
console.log(`child process exited with code ${code}`)
})
import { spawn } from 'node:child_process'
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.stderr.on('data', data => {
console.error(`stderr: ${data}`)
})
ls.on('close', code => {
console.log(`child process exited with code ${code}`)
})
مثال: طريقة مُعقدة للغاية لتشغيل ps ax | grep ssh
const { spawn } = require('node: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.error(`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.error(`grep stderr: ${data}`)
})
grep.on('close', code => {
if (code !== 0) {
console.log(`grep process exited with code ${code}`)
}
})
import { spawn } from 'node: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.error(`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.error(`grep stderr: ${data}`)
})
grep.on('close', code => {
if (code !== 0) {
console.log(`grep process exited with code ${code}`)
}
})
مثال على التحقق من فشل spawn
:
const { spawn } = require('node:child_process')
const subprocess = spawn('bad_command')
subprocess.on('error', err => {
console.error('Failed to start subprocess.')
})
import { spawn } from 'node:child_process'
const subprocess = spawn('bad_command')
subprocess.on('error', err => {
console.error('Failed to start subprocess.')
})
ستستخدم بعض الأنظمة الأساسية (macOS، Linux) قيمة argv[0]
لعنوان العملية بينما سيستخدم البعض الآخر (Windows، SunOS) command
.
يكتب Node.js فوق argv[0]
باستخدام process.execPath
عند بدء التشغيل، لذلك لن تتطابق process.argv[0]
في عملية Node.js الفرعية مع معلمة argv0
الممررة إلى spawn
من الوالد. استرداده باستخدام خاصية process.argv0
بدلاً من ذلك.
إذا تم تمكين خيار signal
، فإن استدعاء .abort()
على AbortController
المقابل مشابه لاستدعاء .kill()
على عملية الطفل باستثناء أن الخطأ الممرر إلى وظيفة الاستدعاء الراجعة سيكون AbortError
:
const { spawn } = require('node:child_process')
const controller = new AbortController()
const { signal } = controller
const grep = spawn('grep', ['ssh'], { signal })
grep.on('error', err => {
// سيتم استدعاء هذا مع err كونه AbortError إذا قامت وحدة التحكم بالإلغاء
})
controller.abort() // يوقف عملية الطفل
import { spawn } from 'node:child_process'
const controller = new AbortController()
const { signal } = controller
const grep = spawn('grep', ['ssh'], { signal })
grep.on('error', err => {
// سيتم استدعاء هذا مع err كونه AbortError إذا قامت وحدة التحكم بالإلغاء
})
controller.abort() // يوقف عملية الطفل
options.detached
أضيف في: v0.7.10
على نظام التشغيل Windows، فإن تعيين options.detached
إلى true
يجعل من الممكن لعملية الطفل الاستمرار في التشغيل بعد خروج العملية الأم. سيكون لعملية الطفل نافذة وحدة تحكم خاصة بها. بمجرد تمكينه لعملية فرعية، لا يمكن تعطيله.
على أنظمة التشغيل غير Windows، إذا تم تعيين options.detached
على true
، فسيتم جعل عملية الطفل قائدًا لمجموعة عمليات وجلسة جديدة. قد تستمر عمليات الطفل في التشغيل بعد خروج العملية الأم بغض النظر عما إذا كانت منفصلة أم لا. راجع setsid(2)
لمزيد من المعلومات.
بشكل افتراضي، ستنتظر العملية الأم خروج عملية الطفل المنفصلة. لمنع العملية الأم من انتظار خروج subprocess
معين، استخدم طريقة subprocess.unref()
. سيؤدي القيام بذلك إلى عدم تضمين حلقة أحداث العملية الأم لعملية الطفل في عداد مرجعها، مما يسمح لعملية الأم بالخروج بشكل مستقل عن عملية الطفل، إلا إذا كانت هناك قناة IPC ثابتة بين عملية الطفل وعمليات الوالدين.
عند استخدام خيار detached
لبدء عملية طويلة التشغيل، فلن تبقى العملية قيد التشغيل في الخلفية بعد خروج العملية الأم إلا إذا تم تزويدها بتكوين stdio
غير متصل بالوالد. إذا تم توارث stdio
لعملية الوالد، فستظل عملية الطفل متصلة بمحطة التحكم.
مثال على عملية طويلة التشغيل، من خلال الفصل وتجاهل مُوصِفات ملفات stdio
الخاصة بوالدها، من أجل تجاهل إنهاء الوالد:
const { spawn } = require('node:child_process')
const process = require('node:process')
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
import { spawn } from 'node:child_process'
import process from 'node:process'
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
بدلاً من ذلك، يمكن إعادة توجيه إخراج عملية الطفل إلى الملفات:
const { openSync } = require('node:fs')
const { spawn } = require('node:child_process')
const out = openSync('./out.log', 'a')
const err = openSync('./out.log', 'a')
const subprocess = spawn('prg', [], {
detached: true,
stdio: ['ignore', out, err],
})
subprocess.unref()
import { openSync } from 'node:fs'
import { spawn } from 'node:child_process'
const out = openSync('./out.log', 'a')
const err = openSync('./out.log', 'a')
const subprocess = spawn('prg', [], {
detached: true,
stdio: ['ignore', out, err],
})
subprocess.unref()
options.stdio
[السجل]
الإصدار | التغييرات |
---|---|
v15.6.0, v14.18.0 | تمت إضافة علم stdio overlapped . |
v3.3.1 | يتم الآن قبول القيمة 0 كوصف ملف. |
v0.7.10 | تمت الإضافة في: v0.7.10 |
يستخدم خيار options.stdio
لتكوين الأنابيب التي يتم إنشاؤها بين عملية الأب والعملية الفرعية. بشكل افتراضي، يتم إعادة توجيه stdin و stdout و stderr للعملية الفرعية إلى تيارات subprocess.stdin
و subprocess.stdout
و subprocess.stderr
المقابلة على كائن ChildProcess
. هذا ما يعادل تعيين options.stdio
مساوياً لـ ['pipe', 'pipe', 'pipe']
.
للملاءمة، قد يكون options.stdio
أحد السلاسل النصية التالية:
'pipe'
: ما يعادل['pipe', 'pipe', 'pipe']
(الافتراضي)'overlapped'
: ما يعادل['overlapped', 'overlapped', 'overlapped']
'ignore'
: ما يعادل['ignore', 'ignore', 'ignore']
'inherit'
: ما يعادل['inherit', 'inherit', 'inherit']
أو[0, 1, 2]
وإلا، فإن قيمة options.stdio
عبارة عن مصفوفة حيث يتوافق كل فهرس مع fd في العملية الفرعية. تتوافق fds 0 و 1 و 2 مع stdin و stdout و stderr، على التوالي. يمكن تحديد fds إضافية لإنشاء أنابيب إضافية بين عملية الأب والعملية الفرعية. القيمة هي واحدة من التالي:
const { spawn } = require('node:child_process')
const process = require('node:process')
// ستستخدم العملية الفرعية stdios الأب.
spawn('prg', [], { stdio: 'inherit' })
// إنشاء عملية فرعية تشترك فقط في stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] })
// فتح fd=4 إضافي، للتفاعل مع البرامج التي تقدم واجهة startd-style.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] })
import { spawn } from 'node:child_process'
import process from 'node:process'
// ستستخدم العملية الفرعية stdios الأب.
spawn('prg', [], { stdio: 'inherit' })
// إنشاء عملية فرعية تشترك فقط في stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] })
// فتح fd=4 إضافي، للتفاعل مع البرامج التي تقدم واجهة startd-style.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] })
تجدر الإشارة إلى أنه عندما يتم إنشاء قناة IPC بين عمليات الأب والفرعية، وتكون العملية الفرعية مثيلًا لـ Node.js، يتم تشغيل العملية الفرعية مع عدم الإشارة إلى قناة IPC (باستخدام unref()
) حتى تقوم العملية الفرعية بتسجيل مُعالِج أحداث لحدث 'disconnect'
أو حدث 'message'
. يسمح هذا للعملية الفرعية بالخروج بشكل طبيعي دون الاحتفاظ بالعملية مفتوحة بواسطة قناة IPC المفتوحة. راجع أيضًا: child_process.exec()
و child_process.fork()
.
إنشاء عملية متزامنة
طرق child_process.spawnSync()
[/api/child_process#child_processspawnsynccommand-args-options] و child_process.execSync()
[/api/child_process#child_processexecsynccommand-options] و child_process.execFileSync()
[/api/child_process#child_processexecfilesyncfile-args-options] متزامنة وستُعيق حلقة أحداث Node.js، مما يُوقف تنفيذ أي كود إضافي حتى تخرج العملية المُنشأة.
تُعدّ المكالمات المُعيقة مثل هذه مفيدة في الغالب لتبسيط مهام البرمجة النصية العامة، ولتبسيط تحميل/معالجة تكوين التطبيق عند بدء التشغيل.
child_process.execFileSync(file[, args][, options])
[السجل]
الإصدار | التغييرات |
---|---|
v16.4.0، v14.18.0 | يمكن أن يكون خيار cwd كائن URL WHATWG باستخدام بروتوكول file: . |
v10.10.0 | يمكن أن يكون خيار input الآن أي TypedArray أو DataView . |
v8.8.0 | أصبح خيار windowsHide مدعومًا الآن. |
v8.0.0 | يمكن أن يكون خيار input الآن Uint8Array . |
v6.2.1، v4.5.0 | يمكن الآن تعيين خيار encoding صراحةً إلى buffer . |
v0.11.12 | تمت الإضافة في: v0.11.12 |
file
<string> اسم أو مسار ملف التنفيذ الذي سيتم تشغيله.args
<string[]> قائمة بحجج السلسلة.options
<Object>cwd
<string> | <URL> دليل العمل الحالي لعملية الطفل.input
<string> | <Buffer> | <TypedArray> | <DataView> القيمة التي سيتم تمريرها كـ stdin إلى العملية المُنشأة. إذا تم تعيينstdio[0]
إلى'pipe'
، فإن توفير هذه القيمة سيُلغيstdio[0]
.stdio
<string> | <Array> تكوين stdio للطفل. انظرchild_process.spawn()
'sstdio
. سيتم إخراجstderr
افتراضيًا إلىstderr
لعملية الأصل ما لم يتم تحديدstdio
. الافتراضي:'pipe'
.env
<Object> أزواج المفتاح والقيمة للبيئة. الافتراضي:process.env
.uid
<number> يُعيّن هوية المستخدم للعملية (انظرsetuid(2)
).gid
<number> يُعيّن هوية المجموعة للعملية (انظرsetgid(2)
).timeout
<number> بالمللي ثانية الحد الأقصى للوقت المسموح به لعملية التشغيل. الافتراضي:undefined
.killSignal
<string> | <integer> قيمة الإشارة التي سيتم استخدامها عند قتل العملية المُنشأة. الافتراضي:'SIGTERM'
.maxBuffer
<number> أكبر قدر من البيانات بالبايت المسموح به على stdout أو stderr. إذا تجاوز الحد، فسيتم إنهاء عملية الطفل. انظر التحذير فيmaxBuffer
و Unicode. الافتراضي:1024 * 1024
.encoding
<string> الترميز المستخدم لجميع مدخلات ومخرجات stdio. الافتراضي:'buffer'
.windowsHide
<boolean> إخفاء نافذة وحدة التحكم الفرعية التي سيتم إنشاؤها عادةً على أنظمة Windows. الافتراضي:false
.shell
<boolean> | <string> إذا كانtrue
، فإنه يُشغّلcommand
داخل shell. يستخدم'/bin/sh'
على Unix، وprocess.env.ComSpec
على Windows. يمكن تحديد shell مختلف كسلسلة. انظر متطلبات Shell و Shell Windows الافتراضي. الافتراضي:false
(بدون shell).
تُعدّ طريقة child_process.execFileSync()
متطابقة عمومًا مع child_process.execFile()
باستثناء أن الطريقة لن تُرجع أي شيء حتى تُغلق عملية الطفل بالكامل. عندما يتم مواجهة مهلة زمنية ويتم إرسال killSignal
، فلن تُرجع الطريقة أي شيء حتى تخرج العملية تمامًا.
إذا اعترضت عملية الطفل إشارة SIGTERM
وعالجتها ولم تخرج، فستظل عملية الأصل تنتظر حتى تخرج عملية الطفل.
إذا انتهت مهلة العملية أو كان لديها رمز خروج غير صفري، فستقذف هذه الطريقة خطأً Error
والذي سيتضمن النتيجة الكاملة لـ child_process.spawnSync()
الأساسية.
إذا تم تمكين خيار shell
، فلا تُمرّر إدخال مستخدم غير مُعقم لهذه الوظيفة. يمكن استخدام أي إدخال يحتوي على أحرف مميزة للـ shell لتنشيط تنفيذ أوامر عشوائية.
const { execFileSync } = require('node:child_process')
try {
const stdout = execFileSync('my-script.sh', ['my-arg'], {
// التقاط stdout و stderr من عملية الطفل. يُلغي السلوك الافتراضي لبث stderr للطفل إلى stderr للأصل
stdio: 'pipe',
// استخدام ترميز utf8 لأنابيب stdio
encoding: 'utf8',
})
console.log(stdout)
} catch (err) {
if (err.code) {
// فشل إنشاء عملية الطفل
console.error(err.code)
} else {
// تم إنشاء الطفل لكنه خرج برمز خروج غير صفري
// يحتوي الخطأ على أي stdout و stderr من الطفل
const { stdout, stderr } = err
console.error({ stdout, stderr })
}
}
import { execFileSync } from 'node:child_process'
try {
const stdout = execFileSync('my-script.sh', ['my-arg'], {
// التقاط stdout و stderr من عملية الطفل. يُلغي السلوك الافتراضي لبث stderr للطفل إلى stderr للأصل
stdio: 'pipe',
// استخدام ترميز utf8 لأنابيب stdio
encoding: 'utf8',
})
console.log(stdout)
} catch (err) {
if (err.code) {
// فشل إنشاء عملية الطفل
console.error(err.code)
} else {
// تم إنشاء الطفل لكنه خرج برمز خروج غير صفري
// يحتوي الخطأ على أي stdout و stderr من الطفل
const { stdout, stderr } = err
console.error({ stdout, stderr })
}
}
child_process.execSync(command[, options])
[السجل]
الإصدار | التغييرات |
---|---|
v16.4.0، v14.18.0 | يمكن أن يكون خيار cwd كائن WHATWG URL باستخدام بروتوكول file: . |
v10.10.0 | يمكن أن يكون خيار input الآن أي TypedArray أو DataView . |
v8.8.0 | يُدعم خيار windowsHide الآن. |
v8.0.0 | يمكن أن يكون خيار input الآن Uint8Array . |
v0.11.12 | تمت الإضافة في: v0.11.12 |
command
<string> الأمر الذي سيتم تشغيله.options
<Object>cwd
<string> | <URL> دليل العمل الحالي لعملية الطفل.input
<string> | <Buffer> | <TypedArray> | <DataView> القيمة التي سيتم تمريرها كمدخل قياسي إلى العملية التي تم إنشاؤها. إذا تم تعيينstdio[0]
على'pipe'
، فإن توفير هذه القيمة سيحل محلstdio[0]
.stdio
<string> | <Array> تكوين stdio للطفل. انظرchild_process.spawn()
'sstdio
. سيتم إخراجstderr
افتراضيًا إلىstderr
لعملية الأصل ما لم يتم تحديدstdio
. الافتراضي:'pipe'
.env
<Object> أزواج قيمة المفتاح للبيئة. الافتراضي:process.env
.shell
<string> قشرة لتشغيل الأمر بها. انظر متطلبات القشرة و قشرة Windows الافتراضية. الافتراضي:'/bin/sh'
على يونكس،process.env.ComSpec
على Windows.uid
<number> يحدد هوية المستخدم للعملية. (انظرsetuid(2)
).gid
<number> يحدد هوية المجموعة للعملية. (انظرsetgid(2)
).timeout
<number> بالمللي ثانية الحد الأقصى للوقت المسموح به لعملية التشغيل. الافتراضي:undefined
.killSignal
<string> | <integer> قيمة الإشارة التي سيتم استخدامها عند قتل العملية التي تم إنشاؤها. الافتراضي:'SIGTERM'
.maxBuffer
<number> أكبر قدر من البيانات بالبايت مسموح به على stdout أو stderr. إذا تجاوز الحد، فسيتم إنهاء عملية الطفل ويتم اقتطاع أي مخرجات. انظر التحذير فيmaxBuffer
و Unicode. الافتراضي:1024 * 1024
.encoding
<string> الترميز المستخدم لجميع مدخلات ومخرجات stdio. الافتراضي:'buffer'
.windowsHide
<boolean> إخفاء نافذة وحدة التحكم الفرعية التي سيتم إنشاؤها عادةً على أنظمة Windows. الافتراضي:false
.
تُعدُّ طريقة child_process.execSync()
متطابقة بشكل عام مع child_process.exec()
باستثناء أن الطريقة لن تُرجع أي شيء حتى يتم إغلاق عملية الطفل بالكامل. عندما يتم مواجهة مهلة زمنية ويتم إرسال killSignal
، فلن تُرجع الطريقة أي شيء حتى تخرج العملية تمامًا. إذا اعترضت عملية الطفل وعالجت إشارة SIGTERM
ولم تخرج، فستنتظر عملية الأصل حتى تخرج عملية الطفل.
إذا انتهت مهلة العملية أو كان لديها رمز خروج غير صفري، فستقوم هذه الطريقة بإلقاء استثناء. سيحتوي كائن Error
على النتيجة الكاملة من child_process.spawnSync()
.
لا تقم أبدًا بنقل مدخلات المستخدم غير المُعالجة إلى هذه الوظيفة. يمكن استخدام أي مدخلات تحتوي على أحرف ميتا قشرة لتشغيل أمر عشوائي.
child_process.spawnSync(command[, args][, options])
[History]
الإصدار | التغييرات |
---|---|
v16.4.0, v14.18.0 | يمكن أن يكون خيار cwd كائن URL من WHATWG باستخدام بروتوكول file: |
v10.10.0 | يمكن أن يكون خيار input الآن أي TypedArray أو DataView . |
v8.8.0 | أصبح خيار windowsHide مدعومًا الآن. |
v8.0.0 | يمكن أن يكون خيار input الآن Uint8Array . |
v5.7.0 | أصبح خيار shell مدعومًا الآن. |
v6.2.1, v4.5.0 | يمكن الآن تعيين خيار encoding صراحةً إلى buffer . |
v0.11.12 | تمت الإضافة في: v0.11.12 |
command
<string> الأمر الذي سيتم تشغيله.args
<string[]> قائمة بحجج السلسلة.options
<Object>cwd
<string> | <URL> دليل العمل الحالي لعملية الطفل.input
<string> | <Buffer> | <TypedArray> | <DataView> القيمة التي سيتم تمريرها كـ stdin إلى العملية التي تم إنشاؤها. إذا تم تعيينstdio[0]
إلى'pipe'
, فإن تزويد هذه القيمة سيتجاوزstdio[0]
.argv0
<string> تعيين قيمةargv[0]
المرسلة إلى عملية الطفل بشكل صريح. سيتم تعيين هذا إلىcommand
إذا لم يتم تحديده.stdio
<string> | <Array> تكوين stdio للطفل. انظرchild_process.spawn()
'sstdio
. افتراضي:'pipe'
.env
<Object> أزواج المفتاح والقيمة للبيئة. افتراضي:process.env
.uid
<number> يحدد هوية المستخدم للعملية (انظرsetuid(2)
).gid
<number> يحدد هوية المجموعة للعملية (انظرsetgid(2)
).timeout
<number> بالميلي ثانية الحد الأقصى لوقت تشغيل العملية. افتراضي:undefined
.killSignal
<string> | <integer> قيمة الإشارة التي سيتم استخدامها عند قتل العملية التي تم إنشاؤها. افتراضي:'SIGTERM'
.maxBuffer
<number> أكبر قدر من البيانات بالبايت مسموح به على stdout أو stderr. إذا تجاوز الحد، فسيتم إنهاء عملية الطفل ويتم اقتطاع أي إخراج. انظر التحذير فيmaxBuffer
و Unicode. افتراضي:1024 * 1024
.encoding
<string> الترميز المستخدم لجميع مدخلات ومخرجات stdio. افتراضي:'buffer'
.shell
<boolean> | <string> إذا كانtrue
، فإنه يشغلcommand
داخل shell. يستخدم'/bin/sh'
على Unix، وprocess.env.ComSpec
على Windows. يمكن تحديد shell مختلف كسلسلة. انظر متطلبات Shell و Shell Windows الافتراضي. افتراضي:false
(بدون shell).windowsVerbatimArguments
<boolean> لا يتم عمل اقتباس أو إفلات للحجج على Windows. يتم تجاهل ذلك على Unix. يتم تعيين هذا علىtrue
تلقائيًا عند تحديدshell
وهو CMD. افتراضي:false
.windowsHide
<boolean> إخفاء نافذة وحدة التحكم الفرعية التي سيتم إنشاؤها عادةً على أنظمة Windows. افتراضي:false
.
العائدات: <Object>
pid
<number> Pid لعملية الطفل.output
<Array> مصفوفة من النتائج من إخراج stdio.stdout
<Buffer> | <string> محتوياتoutput[1]
.stderr
<Buffer> | <string> محتوياتoutput[2]
.status
<number> | <null> رمز الخروج للعملية الفرعية، أوnull
إذا تم إنهاء العملية الفرعية بسبب إشارة.signal
<string> | <null> الإشارة المستخدمة لقتل العملية الفرعية، أوnull
إذا لم يتم إنهاء العملية الفرعية بسبب إشارة.error
<Error> كائن الخطأ إذا فشلت عملية الطفل أو انتهت مهلة الوقت.
طريقة child_process.spawnSync()
متطابقة بشكل عام مع child_process.spawn()
باستثناء أن الدالة لن تعود حتى تغلق عملية الطفل بالكامل. عندما يتم مواجهة مهلة زمنية ويتم إرسال killSignal
، فلن تعود الطريقة حتى تخرج العملية تمامًا. إذا اعترضت العملية وأدارت إشارة SIGTERM
ولم تخرج، فستنتظر عملية الأصل حتى تخرج عملية الطفل.
إذا تم تمكين خيار shell
، فلا تمرر إدخال المستخدم غير المعقم إلى هذه الدالة. يمكن استخدام أي إدخال يحتوي على أحرف معدنية shell لتشغيل تنفيذ أمر عشوائي.
الصف: ChildProcess
مضاف في: v2.2.0
- يمتد من: <EventEmitter>
تمثل مثيلات ChildProcess
عمليات فرعية تم إنشاؤها.
لا يُقصد بإنشاء مثيلات ChildProcess
مباشرةً. بدلاً من ذلك، استخدم طرق child_process.spawn()
، child_process.exec()
، child_process.execFile()
، أو child_process.fork()
لإنشاء مثيلات من ChildProcess
.
الحدث: 'close'
مضاف في: v0.7.7
code
<number> رمز الخروج إذا خرجت العملية الفرعية من تلقاء نفسها.signal
<string> الإشارة التي تم من خلالها إنهاء العملية الفرعية.
يتم إصدار حدث 'close'
بعد انتهاء عملية و إغلاق تدفقات stdio لعملية فرعية. هذا يختلف عن حدث 'exit'
، حيث قد تشترك عمليات متعددة في نفس تدفقات stdio. سيتم دائمًا إصدار حدث 'close'
بعد إصدار 'exit'
بالفعل، أو 'error'
إذا فشلت العملية الفرعية في التوليد.
const { spawn } = require('node:child_process')
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.on('close', code => {
console.log(`child process close all stdio with code ${code}`)
})
ls.on('exit', code => {
console.log(`child process exited with code ${code}`)
})
import { spawn } from 'node:child_process'
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.on('close', code => {
console.log(`child process close all stdio with code ${code}`)
})
ls.on('exit', code => {
console.log(`child process exited with code ${code}`)
})
حدث: 'disconnect'
مضاف في: v0.7.2
يُصدر حدث 'disconnect'
بعد استدعاء طريقة subprocess.disconnect()
في عملية الأب أو process.disconnect()
في عملية الطفل. بعد فصل الاتصال، لم يعد من الممكن إرسال أو استقبال الرسائل، وتصبح خاصية subprocess.connected
قيمة false
.
حدث: 'error'
err
<خطأ> الخطأ.
يُصدر حدث 'error'
كلما:
- تعذر إنشاء العملية.
- تعذر إنهاء العملية.
- فشل إرسال رسالة إلى عملية الطفل.
- تم إلغاء عملية الطفل عبر خيار
signal
.
قد يُصدر حدث 'exit'
أو لا يُصدر بعد حدوث خطأ. عند الاستماع لكل من حدثي 'exit'
و 'error'
، احمِ نفسك من استدعاء دوال المُعالِج عدة مرات عن طريق الخطأ.
انظر أيضًا subprocess.kill()
و subprocess.send()
.
حدث: 'exit'
مضاف في: v0.1.90
code
<رقم> رمز الخروج إذا خرجت عملية الطفل من تلقاء نفسها.signal
<سلسلة> الإشارة التي تم من خلالها إنهاء عملية الطفل.
يُصدر حدث 'exit'
بعد انتهاء عملية الطفل. إذا خرجت العملية، فإن code
هو رمز الخروج النهائي للعملية، وإلا فهو null
. إذا تم إنهاء العملية بسبب استلام إشارة، فإن signal
هو اسم الإشارة النصي، وإلا فهو null
. سيكون أحدهما دائمًا غير null
.
عندما يتم تشغيل حدث 'exit'
، قد لا تزال تيارات إدخال/إخراج عملية الطفل مفتوحة.
تقوم Node.js بإنشاء مُعالِجات إشارات لـ SIGINT
و SIGTERM
، ولن تنتهي عمليات Node.js على الفور بسبب استلام هذه الإشارات. بدلاً من ذلك، ستقوم Node.js بتنفيذ سلسلة من إجراءات التنظيف، ثم ستعيد رفع الإشارة المُعالَجة.
انظر waitpid(2)
.
حدث: 'message'
مضاف في: v0.5.9
message
<Object> كائن JSON مُحلل أو قيمة بدائية.sendHandle
<Handle> | <undefined>undefined
أو كائنnet.Socket
،net.Server
، أوdgram.Socket
.
يتم تشغيل حدث 'message'
عندما تستخدم عملية فرعية process.send()
لإرسال الرسائل.
تمر الرسالة عبر عملية التهيئة والتحليل. قد لا تكون الرسالة الناتجة هي نفسها الرسالة المُرسلة في الأصل.
إذا تم تعيين خيار serialization
إلى 'advanced'
المستخدم عند إنشاء العملية الفرعية، فيمكن أن يحتوي الوسيط message
على بيانات لا يستطيع JSON تمثيلها. راجع التسلسل المتقدم لمزيد من التفاصيل.
حدث: 'spawn'
مضاف في: v15.1.0، v14.17.0
يتم إصدار حدث 'spawn'
بمجرد أن يتم إنشاء العملية الفرعية بنجاح. إذا لم يتم إنشاء العملية الفرعية بنجاح، فلن يتم إصدار حدث 'spawn'
ويتم إصدار حدث 'error'
بدلاً من ذلك.
إذا تم إصداره، يأتي حدث 'spawn'
قبل جميع الأحداث الأخرى وقبل استلام أي بيانات عبر stdout
أو stderr
.
سيتم تشغيل حدث 'spawn'
بغض النظر عما إذا حدث خطأ داخل العملية المُنشأة. على سبيل المثال، إذا تم إنشاء bash some-command
بنجاح، فسيتم تشغيل حدث 'spawn'
، على الرغم من أن bash
قد يفشل في إنشاء some-command
. ينطبق هذا التحذير أيضًا عند استخدام { shell: true }
.
subprocess.channel
[السجل]
الإصدار | التغييرات |
---|---|
v14.0.0 | لم يعد الكائن يكشف عن روابط C++ الأصلية عن طريق الخطأ. |
v7.1.0 | مضاف في: v7.1.0 |
- <Object> أنبوب يمثل قناة IPC إلى العملية الفرعية.
خاصية subprocess.channel
هي مرجع لقناة IPC للعملية الفرعية. إذا لم تكن هناك قناة IPC، فإن هذه الخاصية تكون undefined
.
subprocess.channel.ref()
مضاف في: v7.1.0
هذه الطريقة تجعل قناة IPC تحافظ على حلقة الأحداث لعملية الأب قيد التشغيل إذا تم استدعاء .unref()
من قبل.
subprocess.channel.unref()
مضاف في: v7.1.0
هذه الطريقة تجعل قناة IPC لا تحافظ على حلقة الأحداث لعملية الأب قيد التشغيل، وتسمح لها بالانتهاء حتى أثناء فتح القناة.
subprocess.connected
مضاف في: v0.7.2
- <boolean> مُعيّن إلى
false
بعد استدعاءsubprocess.disconnect()
.
تُشير خاصية subprocess.connected
إلى ما إذا كان لا يزال من الممكن إرسال واستقبال الرسائل من عملية فرعية. عندما تكون 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.exitCode
تُشير خاصية subprocess.exitCode
إلى رمز الخروج لعملية الفرعية. إذا كانت عملية الفرعية لا تزال قيد التشغيل، فسيكون الحقل null
.
subprocess.kill([signal])
مضاف في: v0.1.90
ترسل طريقة subprocess.kill()
إشارة إلى عملية الفرعية. إذا لم يتم تقديم أي وسيطة، فسيتم إرسال إشارة 'SIGTERM'
إلى العملية. راجع signal(7)
للحصول على قائمة بالإشارات المتاحة. تُعيد هذه الدالة true
إذا نجحت kill(2)
، و false
بخلاف ذلك.
const { spawn } = require('node: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')
import { spawn } from 'node: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)
للرجوع.
في Windows، حيث لا توجد إشارات POSIX، سيتم تجاهل وسيطة signal
باستثناء 'SIGKILL'
، 'SIGTERM'
، 'SIGINT'
و 'SIGQUIT'
، وسيتم دائمًا قتل العملية بقوة وفجأة (مثل 'SIGKILL'
). راجع أحداث الإشارة لمزيد من التفاصيل.
في Linux، لن يتم إنهاء عمليات الفرعية لعمليات الفرعية عند محاولة قتل عملية الأب. من المحتمل أن يحدث هذا عند تشغيل عملية جديدة في shell أو باستخدام خيار shell
لـ ChildProcess
:
const { spawn } = require('node: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.js في shell.
}, 2000)
import { spawn } from 'node: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.js في shell.
}, 2000)
subprocess[Symbol.dispose]()
مُضاف في: v20.5.0، v18.18.0
[مستقر: 1 - تجريبي]
مستقر: 1 استقرار: 1 - تجريبي
يطلقُ subprocess.kill()
مع 'SIGTERM'
.
subprocess.killed
مُضاف في: v0.5.10
- <boolean> مُعيّن إلى
true
بعد استخدامsubprocess.kill()
لإرسال إشارة بنجاح إلى عملية الطفل.
تشير خاصية subprocess.killed
إلى ما إذا كانت عملية الطفل قد تلقت بنجاح إشارة من subprocess.kill()
. لا تشير الخاصية killed
إلى أن عملية الطفل قد تم إنهاؤها.
subprocess.pid
مُضاف في: v0.1.90
يُعيد معرفَ العملية (PID) لعملية الطفل. إذا فشلت عملية الطفل في التشغيل بسبب أخطاء، فإن القيمة تكون undefined
ويتم إصدار error
.
const { spawn } = require('node:child_process')
const grep = spawn('grep', ['ssh'])
console.log(`معرف عملية الطفل المُنشأة: ${grep.pid}`)
grep.stdin.end()
import { spawn } from 'node:child_process'
const grep = spawn('grep', ['ssh'])
console.log(`معرف عملية الطفل المُنشأة: ${grep.pid}`)
grep.stdin.end()
subprocess.ref()
مُضاف في: v0.7.10
إنّ استدعاء subprocess.ref()
بعد إجراء مكالمة إلى subprocess.unref()
سيُعيد عدد المرجع المُزال لعملية الطفل، مما يُجبر عملية الأصل على الانتظار حتى تخرج عملية الطفل قبل الخروج بنفسها.
const { spawn } = require('node:child_process')
const process = require('node:process')
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
subprocess.ref()
import { spawn } from 'node:child_process'
import process from 'node:process'
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
subprocess.ref()
subprocess.send(message[, sendHandle[, options]][, callback])
[History]
الإصدار | التغييرات |
---|---|
v5.8.0 | تم دعم معلمة options ، وخيار keepOpen على وجه الخصوص، الآن. |
v5.0.0 | تُرجع هذه الطريقة قيمة منطقية للتحكم في التدفق الآن. |
v4.0.0 | تم دعم معلمة callback الآن. |
v0.5.9 | تمت الإضافة في: v0.5.9 |
message
<Object>sendHandle
<Handle> | <undefined>undefined
، أو كائنnet.Socket
أوnet.Server
أوdgram.Socket
.options
<Object> حجةoptions
، إذا وُجدت، هي كائن يُستخدم لمعلمات إرسال أنواع معينة من المقابض. تدعمoptions
الخصائص التالية:keepOpen
<boolean> قيمة يمكن استخدامها عند تمرير مثيلات منnet.Socket
. عندما تكونtrue
، يبقى المقبس مفتوحًا في عملية الإرسال. الافتراضي:false
.
callback
<Function>القيمة المُرجعة: <boolean>
عندما يتم إنشاء قناة IPC بين العمليات الأبوية والفرعية (أي عند استخدام child_process.fork()
)، يمكن استخدام طريقة subprocess.send()
لإرسال رسائل إلى العملية الفرعية. عندما تكون العملية الفرعية مثيلًا لـ Node.js، يمكن استقبال هذه الرسائل عبر حدث 'message'
.
تمر الرسالة عبر عمليات التجميع والتحليل. قد لا تكون الرسالة الناتجة هي نفسها الرسالة المرسلة في الأصل.
على سبيل المثال، في البرنامج النصي الرئيسي:
const { fork } = require('node:child_process')
const forkedProcess = fork(`${__dirname}/sub.js`)
forkedProcess.on('message', message => {
console.log('PARENT got message:', message)
})
// يتسبب هذا في طباعة العملية الفرعية: CHILD got message: { hello: 'world' }
forkedProcess.send({ hello: 'world' })
import { fork } from 'node:child_process'
const forkedProcess = fork(`${import.meta.dirname}/sub.js`)
forkedProcess.on('message', message => {
console.log('PARENT got message:', message)
})
// يتسبب هذا في طباعة العملية الفرعية: CHILD got message: { hello: 'world' }
forkedProcess.send({ hello: 'world' })
ثم قد يبدو البرنامج النصي الفرعي، 'sub.js'
، كما يلي:
process.on('message', message => {
console.log('CHILD got message:', message)
})
// يتسبب هذا في طباعة العملية الرئيسية: PARENT got message: { foo: 'bar', baz: null }
process.send({ foo: 'bar', baz: NaN })
ستحتوي عمليات Node.js الفرعية على طريقة process.send()
خاصة بها تسمح للعملية الفرعية بإرسال رسائل مرة أخرى إلى العملية الرئيسية.
هناك حالة خاصة عند إرسال رسالة {cmd: 'NODE_foo'}
. الرسائل التي تحتوي على بادئة NODE_
في خاصية cmd
محجوزة للاستخدام داخل نواة Node.js ولن تُصدر في حدث 'message'
الخاص بالعملية الفرعية. بدلاً من ذلك، يتم إصدار هذه الرسائل باستخدام حدث 'internalMessage'
ويتم استهلاكها داخليًا بواسطة Node.js. يجب على التطبيقات تجنب استخدام هذه الرسائل أو الاستماع إلى أحداث 'internalMessage'
لأنها عرضة للتغيير دون إشعار.
حجة sendHandle
الاختيارية التي يمكن تمريرها إلى subprocess.send()
مخصصة لتمرير كائن خادم TCP أو مقبس إلى العملية الفرعية. ستستقبل العملية الفرعية الكائن كحجة ثانية مُمررة إلى دالة المُعالجة المُسجلة في حدث 'message'
. لن يتم إرسال أي بيانات مُستلمة ويتم تخزينها مؤقتًا في المقبس إلى العملية الفرعية. لا يُدعم إرسال مقابس IPC على Windows.
الـ callback
الاختياري هو دالة يتم استدعاؤها بعد إرسال الرسالة ولكن قبل أن تكون العملية الفرعية قد استقبلتها. يتم استدعاء الدالة مع وسيطة واحدة: null
في حالة النجاح، أو كائن Error
في حالة الفشل.
إذا لم يتم توفير دالة callback
ولم يمكن إرسال الرسالة، فسيتم إصدار حدث 'error'
بواسطة كائن ChildProcess
. يمكن أن يحدث هذا، على سبيل المثال، عندما تكون العملية الفرعية قد خرجت بالفعل.
ستُرجع subprocess.send()
قيمة false
إذا تم إغلاق القناة أو عندما يتجاوز تراكم الرسائل غير المرسلة عتبة تجعل من غير الحكمة إرسال المزيد. خلاف ذلك، تُرجع الطريقة قيمة true
. يمكن استخدام دالة callback
لتنفيذ التحكم في التدفق.
مثال: إرسال كائن خادم
يمكن استخدام وسيطة sendHandle
، على سبيل المثال، لإرسال مقبض كائن خادم TCP إلى عملية فرعية كما هو موضح في المثال أدناه:
const { fork } = require('node:child_process')
const { createServer } = require('node:net')
const subprocess = fork('subprocess.js')
// فتح كائن الخادم وإرسال المقبض.
const server = createServer()
server.on('connection', socket => {
socket.end('handled by parent')
})
server.listen(1337, () => {
subprocess.send('server', server)
})
import { fork } from 'node:child_process'
import { createServer } from 'node:net'
const subprocess = fork('subprocess.js')
// فتح كائن الخادم وإرسال المقبض.
const server = createServer()
server.on('connection', socket => {
socket.end('handled by parent')
})
server.listen(1337, () => {
subprocess.send('server', server)
})
ستستقبل العملية الفرعية كائن الخادم على النحو التالي:
process.on('message', (m, server) => {
if (m === 'server') {
server.on('connection', socket => {
socket.end('handled by child')
})
}
})
بمجرد مشاركة الخادم الآن بين العملية الأصلية والفرعية، يمكن للوالد والطفل التعامل مع بعض الاتصالات.
في حين أن المثال أعلاه يستخدم خادمًا تم إنشاؤه باستخدام وحدة node:net
، فإن خوادم وحدة node:dgram
تستخدم نفس سير العمل تمامًا مع استثناءات الاستماع على حدث 'message'
بدلاً من 'connection'
واستخدام server.bind()
بدلاً من server.listen()
. ومع ذلك، هذا مدعوم فقط على أنظمة Unix.
مثال: إرسال كائن مقبس
وبالمثل، يمكن استخدام وسيطة sendHandler
لإرسال مقبض مقبس إلى العملية الفرعية. يُنشئ المثال أدناه طفلين يتعامل كل منهما مع الاتصالات ذات الأولوية "الطبيعية" أو "الخاصة":
const { fork } = require('node:child_process')
const { createServer } = require('node:net')
const normal = fork('subprocess.js', ['normal'])
const special = fork('subprocess.js', ['special'])
// فتح الخادم وإرسال المقابس إلى الطفل. استخدم pauseOnConnect لمنع
// قراءة المقابس قبل إرسالها إلى عملية الطفل.
const server = 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)
import { fork } from 'node:child_process'
import { createServer } from 'node:net'
const normal = fork('subprocess.js', ['normal'])
const special = fork('subprocess.js', ['special'])
// فتح الخادم وإرسال المقابس إلى الطفل. استخدم pauseOnConnect لمنع
// قراءة المقابس قبل إرسالها إلى عملية الطفل.
const server = 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
مقبض المقبس كوسيطة ثانية تم تمريرها إلى دالة استدعاء الحدث:
process.on('message', (m, socket) => {
if (m === 'socket') {
if (socket) {
// تحقق من وجود مقبس العميل.
// من الممكن إغلاق المقبس بين وقت إرساله ووقت استلامه في عملية الطفل.
socket.end(`Request handled with ${process.argv[2]} priority`)
}
}
})
لا تستخدم .maxConnections
على مقبس تم تمريره إلى عملية فرعية. لا يمكن للوالد تتبع وقت تدمير المقبس.
يجب على أي معالجات 'message'
في العملية الفرعية التحقق من وجود socket
، حيث قد يكون الاتصال قد تم إغلاقه خلال الوقت الذي يستغرقه إرسال الاتصال إلى الطفل.
subprocess.signalCode
خاصية subprocess.signalCode
تشير إلى الإشارة التي استلمها عملية الفرعية إن وجدت، وإلا فإنها تكون null
.
subprocess.spawnargs
تمثل خاصية subprocess.spawnargs
القائمة الكاملة من وسيطات سطر الأوامر التي تم تشغيل عملية الفرعية بها.
subprocess.spawnfile
تشير خاصية subprocess.spawnfile
إلى اسم الملف التنفيذي لعملية الفرعية التي تم تشغيلها.
بالنسبة لـ child_process.fork()
، ستكون قيمتها مساوية لـ process.execPath
. بالنسبة لـ child_process.spawn()
، ستكون قيمتها اسم الملف التنفيذي. بالنسبة لـ child_process.exec()
، ستكون قيمتها اسم البرنامج المساعد الذي تم تشغيل عملية الفرعية فيه.
subprocess.stderr
تم الإضافة في: v0.1.90
تيار Readable Stream
يمثل stderr
لعملية الفرعية.
إذا تم إنشاء عملية الفرعية مع ضبط stdio[2]
لأي شيء آخر غير 'pipe'
، فسيكون هذا null
.
subprocess.stderr
هو اسم مستعار لـ subprocess.stdio[2]
. ستشير كلا الخاصيتين إلى نفس القيمة.
يمكن أن تكون خاصية subprocess.stderr
null
أو undefined
إذا تعذر إنشاء عملية الفرعية بنجاح.
subprocess.stdin
مضاف في: v0.1.90
تيار Writable Stream
يمثل stdin
لعملية الطفل.
إذا انتظر إتمام عملية الطفل قراءة جميع مدخلاتها، فلن تستمر عملية الطفل حتى يتم إغلاق هذا التيار عبر end()
.
إذا تم إنشاء عملية الطفل مع ضبط stdio[0]
على أي شيء آخر غير 'pipe'
، فسيكون هذا null
.
subprocess.stdin
هو اسم مستعار لـ subprocess.stdio[0]
. ستشير كلا الخاصيتين إلى نفس القيمة.
يمكن أن تكون خاصية subprocess.stdin
null
أو undefined
إذا تعذر إنشاء عملية الطفل بنجاح.
subprocess.stdio
مضاف في: v0.7.10
مصفوفة متفرقة من الأنابيب إلى عملية الطفل، تتوافق مع المواضع في خيار stdio
الممرر إلى child_process.spawn()
التي تم تعيينها إلى القيمة 'pipe'
. كما تتوفر subprocess.stdio[0]
، وsubprocess.stdio[1]
، وsubprocess.stdio[2]
كـ subprocess.stdin
، وsubprocess.stdout
، وsubprocess.stderr
على التوالي.
في المثال التالي، تم تكوين مُعرّف الملف الوصفي 1
(stdout) للطفل فقط كأنبوب، لذلك فإن subprocess.stdio[1]
للوالد فقط هو تيار، وكل القيم الأخرى في المصفوفة هي null
.
const assert = require('node:assert')
const fs = require('node:fs')
const child_process = require('node:child_process')
const subprocess = child_process.spawn('ls', {
stdio: [
0, // استخدام stdin للوالد للطفل.
'pipe', // توجيه stdout للطفل إلى الوالد.
fs.openSync('err.out', 'w'), // توجيه stderr للطفل إلى ملف.
],
})
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)
import assert from 'node:assert'
import fs from 'node:fs'
import child_process from 'node:child_process'
const subprocess = child_process.spawn('ls', {
stdio: [
0, // استخدام stdin للوالد للطفل.
'pipe', // توجيه stdout للطفل إلى الوالد.
fs.openSync('err.out', 'w'), // توجيه stderr للطفل إلى ملف.
],
})
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.stdio
undefined
إذا تعذر إنشاء عملية الطفل بنجاح.
subprocess.stdout
مُضاف في: v0.1.90
تيار Readable Stream
يمثل stdout
لعملية الطفل.
إذا تم إنشاء عملية الطفل باستخدام stdio[1]
مُعيّنة لأي شيء بخلاف 'pipe'
، فسيكون هذا null
.
subprocess.stdout
هو اسم مستعار لـ subprocess.stdio[1]
. ستشير كلا الخاصيتين إلى نفس القيمة.
const { spawn } = require('node:child_process')
const subprocess = spawn('ls')
subprocess.stdout.on('data', data => {
console.log(`Received chunk ${data}`)
})
import { spawn } from 'node:child_process'
const subprocess = spawn('ls')
subprocess.stdout.on('data', data => {
console.log(`Received chunk ${data}`)
})
يمكن أن تكون خاصية subprocess.stdout
null
أو undefined
إذا تعذّر إنشاء عملية الطفل بنجاح.
subprocess.unref()
مُضاف في: v0.7.10
بشكل افتراضي، ستنتظر عملية الأب انتهاء عملية الطفل المنفصلة. لمنع عملية الأب من انتظار انتهاء subprocess
معيّن، استخدم أسلوب subprocess.unref()
. سيؤدي القيام بذلك إلى عدم تضمين عملية الأب لدورة الحدث لعملية الطفل في عدد مراجعاته، مما يسمح لعملية الأب بالخروج بشكل مستقل عن الطفل، إلا إذا كانت هناك قناة IPC مُنشأة بين عملية الطفل وعملية الأب.
const { spawn } = require('node:child_process')
const process = require('node:process')
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
import { spawn } from 'node:child_process'
import process from 'node:process'
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
maxBuffer
و يونيكود
يحدد خيار maxBuffer
أكبر عدد من البايتات المسموح بها على stdout
أو stderr
. إذا تجاوزت هذه القيمة، فسيتم إنهاء عملية الطفل. وهذا يؤثر على الإخراج الذي يتضمن ترميزات أحرف متعددة البايت مثل UTF-8 أو UTF-16. على سبيل المثال، سترسل console.log('中文测试')
13 بايت مشفرة بـ UTF-8 إلى stdout
على الرغم من وجود 4 أحرف فقط.
متطلبات shell
يجب أن يفهم shell مفتاح -c
. إذا كان shell هو 'cmd.exe'
، فيجب أن يفهم مفاتيح /d /s /c
ويجب أن يكون تحليل سطر الأوامر متوافقًا.
shell افتراضي لنظام Windows
على الرغم من أن Microsoft تحدد أن %COMSPEC%
يجب أن يحتوي على المسار إلى 'cmd.exe'
في بيئة الجذر، إلا أن عمليات الطفل ليست دائمًا خاضعة لنفس المتطلب. لذلك، في دوال child_process
حيث يمكن توليد shell، يتم استخدام 'cmd.exe'
كحل بديل إذا لم يكن process.env.ComSpec
متاحًا.
التسلسل المتقدم
مضاف في: v13.2.0، v12.16.0
تدعم عمليات الطفل آلية تسلسل لـ IPC تستند إلى واجهة برمجة تطبيقات التسلسل لوحدة node:v8
، بناءً على خوارزمية الاستنساخ المُبنيّة. هذا بشكل عام أقوى ويدعم المزيد من أنواع كائنات JavaScript المُدمجة، مثل BigInt
، Map
و Set
، ArrayBuffer
و TypedArray
، Buffer
، Error
، RegExp
إلخ.
ومع ذلك، هذا التنسيق ليس مجموعة فرعية كاملة من JSON، وعلى سبيل المثال، لن يتم تمرير الخصائص المُعيّنة على كائنات من هذه الأنواع المُدمجة من خلال خطوة التسلسل. بالإضافة إلى ذلك، قد لا يكون الأداء مكافئًا لأداء JSON، اعتمادًا على بنية البيانات المُمرّرة. لذلك، تتطلب هذه الميزة التسجيل عن طريق تعيين خيار serialization
إلى 'advanced'
عند استدعاء child_process.spawn()
أو child_process.fork()
.