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:

  1. exec bilan node --version ni chaqirib, stdout ni trim() bilan va trim() siz chiqaring — farqni ko’ring;
  2. Ataylab mavjud bo’lmagan buyruq nomini exec ga bering va error ichida nima kelishini tekshiring;
  3. node -e "process.exit(3)" ni chaqirib, error.code qiymati 3 ekanini tasdiqlang;
  4. Xuddi shu versiya tekshiruvini execFile bilan qayta yozing va argument massivga o’tganini kuzating;
  5. spawn bilan ko’p qator chiqaradigan jarayon ochib, bo’laklarni o’zgaruvchiga to’plang va close hodisasida bir marta chiqaring;
  6. spawn bilan ochilgan jarayonni kill() bilan to’xtatib, close hodisasida signal qiymatini ko’ring.

4-qadam eng muhimi: execFile ga o’tish shell injection xavfini butunlay yo’q qiladi.

Qisqacha xulosa

  • child_process Node.js’dan boshqa dasturni ishga tushiradi.
  • exec chiqishni bir butun beradi, spawn esa oqim bo’lib bo’lak-bo’lak.
  • Callback tartibi error, stdout, stderr — xato birinchi keladi.
  • Buyruq noldan farqli kod bilan tugasa, error.code o’sha kodni saqlaydi.
  • Chiqish katta yoki jarayon uzoq ishlasa — spawn tanlanadi.
  • Foydalanuvchi bergan matn hech qachon exec buyrug’iga yopishtirilmaydiexecFile va argumentlar massivi ishlatiladi.
  • child.kill() jarayonni to’xtatadi, unda close hodisasiga signal keladi.

Keyingi darsda worker_threads — og’ir hisobni alohida oqimga chiqarish.

Bu dars foydali bo'ldimi?

marta ko'rildi