Node.js child_process: boshqa dasturni chaqirish
Ba’zan kerakli ish allaqachon boshqa dasturda bajarilgan: rasmni
ffmpeg siqadi, omborni git boshqaradi, arxivni tar ochadi. Ularni
qaytadan JavaScript’da yozish o’rniga, Node.js’dan turib chaqirish
mumkin. Buning uchun child_process moduli bor.
Jarayon nima
Modulda uchta asosiy funksiya bor. Farqini oldindan ko’rib qo’yamiz:
| Funksiya | Qachon ishlatiladi | Chiqishni qanday beradi |
|---|---|---|
exec |
Qisqa buyruq, chiqish kichik | Bir butun satr sifatida |
execFile |
Shell kerak bo’lmaganda | Bir butun satr sifatida |
spawn |
Uzoq ishlaydigan, chiqish katta | Oqim bo’lib bo’lak-bo’lak |
exec — eng sodda yo’l
exec-demo.js faylini yarating:
const { exec } = require("node:child_process");
exec("node --version", (error, stdout, stderr) => {
if (error) {
console.log("Xato:", error.message);
return;
}
console.log("Chiqish:", stdout.trim());
console.log("stderr bo'sh:", stderr === "");
});
node exec-demo.js
Chiqish: v24.14.1
stderr bo'sh: true
Callback uchta qiymat oladi. Bu asinxron kod darsidagi tanish tartib: xato birinchi parametrda keladi.
| Parametr | Nima |
|---|---|
error |
Buyruq muvaffaqiyatsiz tugasa Error, aks holda null |
stdout |
Buyruqning oddiy chiqishi |
stderr |
Buyruqning xato oqimiga yozgani |
stdout oxirida yangi qator belgisi qoladi, shuning uchun trim()
ishlatildi.
Xato kodini tekshirish
Buyruq noldan farqli kod bilan tugasa, error to’ladi. exit-code-demo.js:
const { exec } = require("node:child_process");
exec("node -e \"process.exit(3)\"", (error) => {
if (error) {
console.log("Chiqish kodi:", error.code);
return;
}
console.log("Xatosiz tugadi");
});
node exit-code-demo.js
Chiqish kodi: 3
process darsida ko’rgan chiqish kodi
shu yerda qaytib keldi: 0 muvaffaqiyat, boshqasi xato.
execFile — shellsiz chaqiruv
exec buyruqni shell orqali yuboradi. execFile esa dasturni
to’g’ridan-to’g’ri ishga tushiradi va argumentlarni alohida massivda
oladi.
const { execFile } = require("node:child_process");
execFile("node", ["--version"], (error, stdout) => {
if (error) {
console.log("Xato:", error.message);
return;
}
console.log("Versiya:", stdout.trim());
});
node exec-file-demo.js
Versiya: v24.14.1
Natija bir xil, lekin yo’l boshqacha: bu yerda oraliqda shell yo’q. Nega bu muhim ekanini quyida ko’rasiz.
spawn — katta chiqishni oqim bilan olish
exec butun chiqishni xotirada to’playdi. Chiqish katta bo’lsa bu
muammo. spawn esa natijani oqim sifatida
beradi.
spawn-demo.js:
const { spawn } = require("node:child_process");
const child = spawn("node", [
"-e",
"for (let i = 1; i <= 3; i++) console.log('Qator ' + i);",
]);
let output = "";
child.stdout.on("data", (chunk) => {
output += chunk.toString();
});
child.stderr.on("data", (chunk) => {
console.log("Xato oqimi:", chunk.toString().trim());
});
child.on("close", (code) => {
console.log("Tugadi, kod:", code);
console.log("To'plangan chiqish:");
console.log(output.trim());
});
node spawn-demo.js
Tugadi, kod: 0
To'plangan chiqish:
Qator 1
Qator 2
Qator 3
child.stdout — oddiy o’qish oqimi, data va close hodisalari bilan
ishlaydi.
Qaysi birini tanlash
| Holat | Tanlov |
|---|---|
git --version kabi qisqa buyruq |
exec |
| Argumentlar o’zgaruvchidan keladi | execFile yoki spawn |
| Chiqish megabaytlarda | spawn |
| Jarayon uzoq ishlaydi, natija bosqichma-bosqich kerak | spawn |
Eng muhim qism: foydalanuvchi kiritmasi
Endi xavfsizlik. Quyidagi yozuv jiddiy xato — nega ekanini tushunish shart.
Bu mantiq SQL injection bilan bir xil: ma’lumotni buyruqdan ajratish kerak. U yerda parametrli so’rov, bu yerda argumentlar massivi.
Jarayonni to’xtatish
Uzoq ishlaydigan jarayonni majburan yopish mumkin:
const { spawn } = require("node:child_process");
// Uch soniya kutadigan jarayon
const child = spawn("node", ["-e", "setTimeout(() => {}, 3000)"]);
console.log("Jarayon ochildi, id:", child.pid);
// Bir soniyadan keyin to'xtatamiz
setTimeout(() => {
child.kill();
console.log("To'xtatish signali yuborildi");
}, 1000);
child.on("close", (code, signal) => {
console.log("Yopildi. Kod:", code, "Signal:", signal);
});
node kill-demo.js
Jarayon ochildi, id: 18432
To'xtatish signali yuborildi
Yopildi. Kod: null Signal: SIGTERM
Jarayon o’zi tugamay, tashqaridan to’xtatilganda code o’rniga
signal to’ladi.
Amaliy mashq
node-start papkasida bajaring:
execbilannode --versionni chaqirib,stdoutnitrim()bilan vatrim()siz chiqaring — farqni ko’ring;- Ataylab mavjud bo’lmagan buyruq nomini
execga bering vaerrorichida nima kelishini tekshiring; node -e "process.exit(3)"ni chaqirib,error.codeqiymati3ekanini tasdiqlang;- Xuddi shu versiya tekshiruvini
execFilebilan qayta yozing va argument massivga o’tganini kuzating; spawnbilan ko’p qator chiqaradigan jarayon ochib, bo’laklarni o’zgaruvchiga to’plang vaclosehodisasida bir marta chiqaring;spawnbilan ochilgan jarayonnikill()bilan to’xtatib,closehodisasidasignalqiymatini ko’ring.
4-qadam eng muhimi: execFile ga o’tish shell injection xavfini
butunlay yo’q qiladi.
Qisqacha xulosa
child_processNode.js’dan boshqa dasturni ishga tushiradi.execchiqishni bir butun beradi,spawnesa oqim bo’lib bo’lak-bo’lak.- Callback tartibi
error,stdout,stderr— xato birinchi keladi. - Buyruq noldan farqli kod bilan tugasa,
error.codeo’sha kodni saqlaydi. - Chiqish katta yoki jarayon uzoq ishlasa —
spawntanlanadi. - Foydalanuvchi bergan matn hech qachon
execbuyrug’iga yopishtirilmaydi —execFileva argumentlar massivi ishlatiladi. child.kill()jarayonni to’xtatadi, undaclosehodisasigasignalkeladi.
Keyingi darsda worker_threads — og’ir hisobni alohida oqimga chiqarish.