Node.js içinden başka bir programı çalıştırmak için node:child_process modülünü kullanırsınız. Kısa cevap şudur: çıktıyı tek parça halinde istiyorsanız ve kabuk özelliğine ihtiyacınız yoksa execFile(), uzun süren ya da çok çıktı üreten işler için akış tabanlı spawn(), kabuk sözdizimi (boru, yönlendirme, joker karakter) gerekiyorsa exec(), başka bir Node.js betiğiyle mesajlaşmanız gerekiyorsa fork() doğru seçimdir. Dördü de aslında spawn() üzerine kurulu kolaylık fonksiyonlarıdır.
Bu yazıda dört fonksiyonun farkını, çıkış kodu ve sinyal ayrımını, ENOENT gibi başlatma hatalarını, timeout ve maxBuffer sınırlarını, senkron sürümlerin olay döngüsünü nasıl durdurduğunu, kabuk enjeksiyonu riskini ve Windows ile Linux arasındaki davranış farklarını resmî belgeye dayanarak anlatıyoruz. Bütün örnekler Node.js v26.13.0 ile çalıştırıldı; alt süreç olarak çoğunlukla process.execPath (çalışan node programının yolu) kullanıldı, böylece örnekler hem Windows hem Linux üzerinde aynı sonucu verir. Modül belgede Stability: 2 - Stable olarak işaretli.
Dört fonksiyon, tek temel: spawn

Belgeye göre spawn(), exec(), execFile() ve fork() asenkron çalışır ve hepsi bir ChildProcess nesnesi döndürür. Bu nesne bir EventEmitter olduğu için alt sürecin yaşam döngüsünü spawn, exit, close, error ve message olaylarıyla izlersiniz. exec() ve execFile() ek olarak, süreç bittiğinde (error, stdout, stderr) parametreleriyle çağrılan bir geri çağırma fonksiyonu kabul eder; çıktıyı sizin yerinize biriktirir.
Farkı belirleyen iki soru vardır: komut bir kabuk (Unix'te /bin/sh, Windows'ta process.env.ComSpec) içinde mi çalışacak, ve çıktıyı bellekte toplu olarak mı yoksa akış olarak mı alacaksınız? Aşağıdaki tablo belgedeki varsayılanları özetler.
| Fonksiyon | Kabuk | Çıktı | IPC kanalı | Tipik kullanım |
|---|---|---|---|---|
| exec(command) | Evet, her zaman | Tamponlanır, callback ile gelir | Yok | Boru ve yönlendirme gereken kısa kabuk komutları |
| execFile(file, args) | Hayır (shell seçeneğiyle açılabilir) | Tamponlanır, callback ile gelir | Yok | Bir programı argümanlarla güvenle çalıştırmak |
| spawn(command, args) | Hayır (shell seçeneğiyle açılabilir) | Akış: stdout ve stderr stream | stdio içinde ipc ile | Uzun süren işler, büyük çıktı |
| fork(modulePath, args) | Desteklenmez | Varsayılan olarak ebeveynden miras | Her zaman var | Node.js betikleri arasında mesajlaşma |
Tamponlanan fonksiyonlarda maxBuffer varsayılan olarak 1024 * 1024 bayttır; bu sınır aşılırsa alt süreç sonlandırılır. Akış tabanlı spawn() ise böyle bir sınır uygulamaz, veriyi geldikçe size verir. Stream mantığını ayrıntılı görmek için Node.js stream rehberine bakabilirsiniz.
execFile ile program çalıştırmak ve çıktıyı almak
En sık ihtiyaç, bir programı birkaç argümanla çalıştırıp çıktısını metin olarak almaktır. Bunun için execFile() fonksiyonunu util.promisify() ile Promise döndüren hale getirmek pratik bir yoldur. Belge, promisify edilmiş sürümün { stdout, stderr } nesnesiyle çözüldüğünü, oluşan ChildProcess nesnesinin de Promise'e child özelliği olarak eklendiğini söyler. Aşağıdaki örnekte ikinci çağrı, argümanları olduğu gibi yazan küçük bir argv.mjs betiğini çalıştırıyor.
// argv.mjs: aldığı argümanları olduğu gibi yazar
console.log(process.argv.slice(2));import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
const execFileP = promisify(execFile);
// process.execPath: şu an çalışan node programının tam yolu
const { stdout } = await execFileP(process.execPath, ['--version']);
console.log(stdout.trim());
// çıktı: v26.13.0
// Kullanıcıdan gelen metin tek bir argüman olarak gider, kabuk yorumlamaz
const { stdout: out2 } = await execFileP(process.execPath, ['argv.mjs', 'rapor; echo hack', '$HOME']);
console.log(out2.trim());
// çıktı: [ 'rapor; echo hack', '$HOME' ]İkinci çıktıya dikkat edin: rapor; echo hack ve $HOME değerleri yorumlanmadan, birer argüman olarak alt sürece ulaştı. Kabuk olmadığı için noktalı virgül komut ayırıcı, $ işareti de değişken genişletme anlamına gelmiyor. Belge de execFile() için kabuk açılmadığından G/Ç yönlendirmesi ve joker karakter genişletmesinin desteklenmediğini, ama bu yüzden exec() sürümünden biraz daha verimli olduğunu belirtir.
Çıktının sonunda satır sonu karakteri bulunduğu için trim() çağırdık. encoding seçeneği varsayılan olarak utf8 olduğundan stdout bir dize olarak gelir; encoding: 'buffer' verirseniz Buffer alırsınız. İkili veri üreten programlarda (görüntü, arşiv) Buffer kullanmak gerekir; ayrıntı için Buffer yazısına bakabilirsiniz.
spawn: çıktıyı akış olarak okumak
spawn() çıktıyı biriktirmez; subprocess.stdout ve subprocess.stderr okunabilir stream'lerdir, subprocess.stdin ise yazılabilir bir stream'dir. Bu yüzden saatlerce çalışan bir işi, büyük bir dosya üreten bir aracı ya da canlı log akışını izlemek için uygundur. Örnekte alt program olarak üç satır yazan, stderr'e bir uyarı basan ve 3 koduyla çıkan bir betik kullanıyoruz.
// uzun.mjs: üç satır yazıp 3 koduyla çıkan küçük alt program
for (let i = 1; i <= 3; i++) {
console.log(`satır ${i}`);
}
console.error('uyarı: disk az');
process.exitCode = 3;import { spawn } from 'node:child_process';
import { once } from 'node:events';
const cocuk = spawn(process.execPath, ['uzun.mjs']);
cocuk.stdout.setEncoding('utf8');
cocuk.stderr.setEncoding('utf8');
let cikti = '';
let hata = '';
cocuk.on('spawn', () => console.log('başladı, pid sayı mı:', typeof cocuk.pid === 'number'));
cocuk.stdout.on('data', (parca) => (cikti += parca));
cocuk.stderr.on('data', (parca) => (hata += parca));
const [kod, sinyal] = await once(cocuk, 'close');
console.log('stdout satır sayısı:', cikti.trim().split('\n').length);
console.log('stderr:', hata.trim());
console.log('close:', kod, sinyal);
console.log('exitCode:', cocuk.exitCode);
// çıktı: başladı, pid sayı mı: true
// çıktı: stdout satır sayısı: 3
// çıktı: stderr: uyarı: disk az
// çıktı: close: 3 null
// çıktı: exitCode: 3Burada üç olay arasındaki fark önemlidir. spawn olayı süreç başarıyla oluşturulduğunda, her şeyden önce gelir. exit olayı süreç bittiğinde gelir ama belgeye göre o anda stdio akışları hâlâ açık olabilir. close olayı ise süreç bittikten ve stdio akışları kapandıktan sonra, her zaman exit olayından sonra gelir. Çıktının tamamını işledikten sonra karar vermek istiyorsanız close olayını bekleyin. Her iki olayda da code ve signal parametrelerinden biri mutlaka null dışıdır: süreç kendi çıktıysa kod, sinyalle sonlandırıldıysa sinyal adı gelir.
Belge önemli bir tuzağı da açıkça yazar: ebeveyn ile çocuk arasındaki borular sınırlı ve platforma bağlı bir kapasiteye sahiptir. Çocuk bu kapasiteden fazla veri yazar ve siz okumazsanız, çocuk süreç tamponun boşalmasını bekleyerek kilitlenir. Çıktıyla ilgilenmiyorsanız stdio: 'ignore', çıktının doğrudan terminalinize akmasını istiyorsanız stdio: 'inherit' verin.
| stdio değeri | Anlamı |
|---|---|
| pipe (varsayılan) | Ebeveyn ile çocuk arasında boru açılır, subprocess.stdout gibi stream olarak erişilir |
| inherit | Çocuk ebeveynin stdin, stdout ve stderr akışlarını kullanır |
| ignore | İlgili tanımlayıcı /dev/null benzeri bir hedefe bağlanır, çıktı atılır |
| ipc | Mesajlaşma kanalı açar, subprocess.send() kullanılabilir hale gelir (en fazla bir tane) |
| Sayı veya Stream | Ebeveyndeki açık bir dosya tanımlayıcısını ya da stream'i çocukla paylaşır |
Hata durumları: çıkış kodu, ENOENT ve sinyaller

Alt süreçle ilgili iki tür başarısızlık vardır ve ikisini ayırt etmeniz gerekir. Birincisi, program çalıştı ama sıfırdan farklı bir kodla çıktı. Belgeye göre bu durumda exec() ve execFile() geri çağırmasına bir Error gelir, error.code çıkış kodunu, error.signal de süreci sonlandıran sinyali taşır. Promisify edilmiş sürüm aynı hata nesnesiyle reddedilir ve hataya stdout ile stderr özellikleri de eklenir; yani başarısız komutun çıktısını kaybetmezsiniz.
İkincisi, program hiç başlatılamadı. Komut bulunamazsa ya da cwd olarak verdiğiniz klasör yoksa belge alt sürecin ENOENT hatası yaydığını söyler. Bu hata error olayıyla gelir ve bu durumda spawn olayı hiç tetiklenmez.
import { execFile, spawn } from 'node:child_process';
import { promisify } from 'node:util';
const execFileP = promisify(execFile);
// 1) Program çalıştı ama 0 dışı kodla çıktı: promise reddedilir
try {
await execFileP(process.execPath, ['uzun.mjs']);
} catch (err) {
console.log(err.code, JSON.stringify(err.stdout), JSON.stringify(err.stderr));
}
// çıktı: 3 "satır 1\nsatır 2\nsatır 3\n" "uyarı: disk az\n"
// 2) Program hiç bulunamadı: 'error' olayı, code ENOENT
const yok = spawn('boyle-bir-komut-yok');
yok.on('error', (err) => {
console.log(err.code, err.syscall);
});
// çıktı: ENOENT spawn boyle-bir-komut-yokerror olayının tetiklendiği diğer durumlar da belgede listelenir: süreç öldürülemediğinde, çocuğa mesaj gönderilemediğinde ve süreç signal seçeneğiyle iptal edildiğinde. Belge, hata oluştuktan sonra exit olayının gelebileceğini ya da gelmeyebileceğini, ikisini birden dinliyorsanız işleyicinizin iki kez çalışmasına karşı önlem almanızı önerir. Sistem hata kodlarının (ENOENT, EACCES, EPERM) genel anlamları için sistem hataları yazısına bakabilirsiniz.
Sinyalle sonlanan süreçlerde exitCode değeri null olur, signalCode ise sinyal adını taşır. Belge, bu sinyali POSIX çıkış koduna çevirmek için util.convertProcessSignalToExitCode() fonksiyonunu gösterir. Kendi betiğinizin çıkış kodunu nasıl ayarlayacağınızı process.argv ve çıkış kodları yazısında anlattık.
Zaman aşımı, maxBuffer ve senkron sürümler
Bir alt sürecin sonsuza kadar asılı kalmasını istemezsiniz. timeout seçeneği sıfırdan büyükse, süreç bu kadar milisaniyeden uzun çalıştığında ebeveyn ona killSignal seçeneğindeki sinyali (varsayılan SIGTERM) gönderir. Çok konuşan bir programın belleğinizi doldurmasını da maxBuffer ile sınırlarsınız. Senkron spawnSync() ise sonucu tek bir nesne olarak döndürür ve input seçeneğiyle çocuğun stdin akışına veri yazmanıza izin verir. Aşağıdaki örnekte buyuk.mjs, stdin'den okuduğunu büyük harfe çeviren küçük bir betiktir.
// buyuk.mjs: stdin'den gelen metni büyük harfe çevirip yazar
let veri = '';
process.stdin.setEncoding('utf8');
process.stdin.on('data', (p) => (veri += p));
process.stdin.on('end', () => process.stdout.write(veri.toLocaleUpperCase('tr-TR')));import { spawnSync, execFile } from 'node:child_process';
// spawnSync: input stdin'e yazılır, sonuç tek bir nesne olarak döner
const sonuc = spawnSync(process.execPath, ['buyuk.mjs'], {
input: 'merhaba dünya',
encoding: 'utf8',
});
console.log(sonuc.status, sonuc.signal, JSON.stringify(sonuc.stdout));
// çıktı: 0 null "MERHABA DÜNYA"
// maxBuffer aşılırsa çocuk sonlandırılır, çıktı kesilir
execFile(process.execPath, ['-p', "'x'.repeat(5000)"], { maxBuffer: 1000 }, (err, stdout) => {
console.log(err.code);
console.log(err.message);
console.log('gelen bayt:', stdout.length);
});
// çıktı: ERR_CHILD_PROCESS_STDIO_MAXBUFFER
// çıktı: stdout maxBuffer length exceeded
// çıktı: gelen bayt: 1000
// timeout: süre dolunca killSignal (varsayılan SIGTERM) gönderilir
execFile(process.execPath, ['-e', 'setTimeout(() => {}, 10000)'], { timeout: 300 }, (err) => {
console.log('killed:', err.killed, 'signal:', err.signal, 'code:', err.code);
});
// çıktı: killed: true signal: SIGTERM code: nullZaman aşımında err.killed değeri true, err.code değeri null, sinyal de SIGTERM oldu; bu çıktı Windows üzerinde alındı. maxBuffer için belge bir Unicode uyarısı yapar: sınır karakter değil bayt sayısıdır. UTF-8 ile kodlanmış çok baytlı karakterler (Türkçe harfler dahil) sınıra beklediğinizden önce ulaşır. Örnekte 1000 baytlık sınır aşıldığında çocuk sonlandırıldı ve elimize yalnızca ilk 1000 bayt geçti.
execSync(), execFileSync() ve spawnSync(), alt süreç tamamen kapanana kadar geri dönmez. Belge, bu bloklayıcı çağrıların genel amaçlı betiklerde ve uygulama açılışında yapılandırma yüklerken işe yaradığını, ama olay döngüsünü durdurdukları için performansı ciddi biçimde etkileyebildiğini söyler. Node.js Learn rehberi de bu üç fonksiyonu bir sunucuda kaçınılması gereken senkron API'ler arasında sayar. Ayrıca execSync() ve execFileSync() zaman aşımında ya da sıfırdan farklı çıkış kodunda hata fırlatır; hata nesnesi spawnSync() sonucunun tamamını içerir. Olay döngüsünü bloklamanın sonuçlarını Node.js performans yazısında ele aldık.
fork ve IPC ile Node.js süreçleri arasında mesajlaşma
fork(), yeni bir Node.js süreci başlatan özel bir spawn() çağrısıdır. Fark, iki süreç arasında hazır bir IPC (süreçler arası iletişim) kanalının kurulmasıdır: ebeveyn subprocess.send() ile, çocuk process.send() ile mesaj gönderir; karşı taraf bunları message olayıyla alır. Varsayılan serileştirme JSON'dır; belge, mesajın serileştirilip yeniden ayrıştırıldığını ve bu yüzden gönderdiğinizle birebir aynı olmayabileceğini hatırlatır.
import { fork } from 'node:child_process';
if (process.argv[2] === 'isci') {
// Çocuk taraf: process.send ile ebeveyne cevap verir
process.on('message', (mesaj) => {
const toplam = mesaj.sayilar.reduce((a, b) => a + b, 0);
process.send({ toplam, bagli: process.connected });
process.disconnect(); // kanal kapanınca çocuk doğal olarak biter
});
} else {
const cocuk = fork(import.meta.filename, ['isci']);
cocuk.on('message', (cevap) => {
console.log('ebeveyn aldı:', cevap);
});
cocuk.on('exit', (kod) => console.log('çocuk çıktı, kod:', kod));
cocuk.send({ sayilar: [4, 8, 15, 16, 23, 42] });
}
// çıktı: ebeveyn aldı: { toplam: 108, bagli: true }
// çıktı: çocuk çıktı, kod: 0Örnekte aynı dosya hem ebeveyn hem çocuk olarak çalışıyor; hangi rolde olduğunu process.argv[2] ile anlıyor. Çocuk işini bitirince process.disconnect() çağırıyor, kanal kapanıyor ve süreç başka bir iş kalmadığı için kendiliğinden çıkıyor. Belgeye göre çocuk bir message ya da disconnect dinleyicisi kaydedene kadar IPC kanalı unref() durumundadır, yani yalnızca açık kanal yüzünden süreç ayakta kalmaz.
Map, Set, BigInt ya da Buffer göndermeniz gerekiyorsa serialization: 'advanced' seçeneği yapılandırılmış klonlamaya dayalı daha güçlü bir biçim sunar. Belge bu biçimin JSON'un tam bir üst kümesi olmadığını ve performansın verinin yapısına göre değişebileceğini de belirtir. Bir uyarı daha: fork ile açılan her çocuk kendi belleğine ve kendi V8 örneğine sahip bağımsız bir süreçtir, belge çok sayıda Node.js alt süreci başlatmayı önermez. Aynı süreç içinde CPU yoğun iş için worker_threads yazısına, çok çekirdekli HTTP sunucusu için cluster ve PM2 yazısına bakın.
Kabuk güvenliği: exec neden tehlikeli olabilir?
Belge exec() ve execSync() için kalın harflerle şunu yazar: temizlenmemiş kullanıcı girdisini asla bu fonksiyonlara vermeyin. Komut dizesi doğrudan kabuk tarafından işlendiği için içinde noktalı virgül, ters tırnak, $() ya da boru karakteri bulunan bir girdi, sizin istemediğiniz komutları çalıştırabilir. Aynı uyarı shell seçeneği açık olan execFile(), spawn() ve senkron sürümler için de geçerlidir.
Güvenli yol, programı kabuksuz çalıştırıp kullanıcı verisini argüman dizisinin bir elemanı olarak vermektir; yukarıdaki argv.mjs örneği bunu gösteriyordu. Node.js bu konuda bir adım daha atmış: execFile() veya spawn() çağrısına shell: true ile birlikte args dizisi vermek DEP0190 koduyla kullanımdan kaldırıldı. Belgeye göre bu, v24.0.0 ile çalışma zamanı uyarısına dönüştü; çünkü bu durumda argümanlar kaçışlanmadan yalnızca boşlukla birleştirilir.
import { execFile } from 'node:child_process';
// shell: true ile args dizisi vermek DEP0190 uyarısı üretir
execFile('echo', ['merhaba'], { shell: true }, (err, stdout) => {
console.log('çıktı:', stdout.trim());
});
// çıktı: (node:PID) [DEP0190] DeprecationWarning: Passing args to a child process with shell option true can lead to security vulnerabilities, as the arguments are not escaped, only concatenated.
// çıktı: (Use `node --trace-deprecation ...` to show where the warning was created)
// çıktı: çıktı: merhabaUyarı stderr'e yazılır, PID değeri her çalıştırmada değişir. Kullanımdan kaldırma uyarılarının türlerini ve nasıl yönetildiğini deprecation uyarıları yazısında anlattık. Kabuk özelliği gerçekten gerekiyorsa (boru, yönlendirme), komut dizesini sabit tutun ve değişken kısmı kabuğa hiç sokmayın; örneğin girdiyi stdin üzerinden verin.
Windows ve Linux arasındaki farklar

Belge, platforma göre değişen davranışları açıkça listeler; aynı kodun iki sistemde farklı sonuç vermesinin en yaygın sebepleri bunlardır:
- .bat ve .cmd dosyaları: Windows'ta bu dosyalar terminal olmadan kendi başlarına çalıştırılamaz, bu yüzden
execFile()ile başlatılamaz. Belgedeki yollarexec()kullanmak ya dacmd.exeprogramını/cargümanıyla başlatmaktır.spawn()ileshellseçeneği de mümkündür ama DEP0190 yüzünden önerilmez. Dosya adında boşluk varsa tırnak içine alınmalıdır. - Varsayılan kabuk: Unix'te
/bin/sh, Windows'taprocess.env.ComSpeckullanılır; ComSpec yoksa yedek olarakcmd.exedevreye girer. Kabuk Unix tarafında-c, cmd.exe tarafında/d /s /canahtarlarını anlamalıdır. - Ortam değişkenleri: Windows'ta değişken adları büyük küçük harfe duyarsızdır.
envnesnesinde hemPATHhemPathvarsa Node.js anahtarları sıralar ve yalnızca ilk eşleşeni çocuğa geçirir. - Sinyaller: Windows'ta POSIX sinyalleri yoktur.
SIGKILL,SIGTERM,SIGINTveSIGQUIT(ve Windows'ta adı bilinen diğer sinyaller) süreci zorla ve aniden sonlandırır.SIGWINCHiçinkill()ENOSYS fırlatır; Windows'ta karşılığı olmayan bir ad (örneğinSIGSTOP)ERR_UNKNOWN_SIGNALhatası verir. - Torun süreçler: Linux'ta bir çocuğu öldürmek, onun başlattığı alt süreçleri öldürmez. Bu özellikle
shellseçeneğiyle ya da bir kabuk içinden başlatılan programlarda görülür; kabuk ölür ama içindeki program çalışmaya devam edebilir. - detached: Windows'ta
detached: true, çocuğun ebeveyn çıktıktan sonra da çalışmasını sağlar ve çocuğa ayrı bir konsol penceresi açar. Diğer platformlarda çocuk yeni bir süreç grubunun ve oturumun lideri yapılır.
Arka planda bağımsız süreç: detached ve unref
Bazen ebeveyn süreç işini bitirip çıkarken, başlattığı bir işin arka planda devam etmesini istersiniz. Belge bunun için üç parçanın birlikte gerektiğini anlatır: detached: true, ebeveynin terminaline bağlı olmayan bir stdio yapılandırması (örneğin 'ignore' ya da bir log dosyası) ve ebeveynin çocuğu beklememesi için subprocess.unref(). Varsayılan durumda ebeveyn, ayrılmış çocuğun bile çıkmasını bekler; unref() çocuğu olay döngüsünün referans sayımından çıkarır. Arada bir IPC kanalı varsa ebeveyn yine de bağımsız çıkamaz.
import { spawn } from 'node:child_process';
// Ebeveynden bağımsız çalışacak bir arka plan işi
const is = spawn(process.execPath, ['-e', 'setTimeout(() => {}, 500)'], {
detached: true,
stdio: 'ignore', // ebeveynin terminaline bağlı kalmasın
windowsHide: true, // Windows'ta ayrı konsol penceresi gösterme
});
is.unref(); // ebeveyn bu çocuğu beklemeden çıkabilsin
console.log('ebeveyn çıkıyor, çocuk pid var mı:', Number.isInteger(is.pid));
// çıktı: ebeveyn çıkıyor, çocuk pid var mı: trueKalıcı servisler için bu yöntem yerine bir süreç yöneticisi kullanmak daha sağlıklıdır; sunucunuzda uygulamayı açılışta başlatıp çökünce yeniden ayağa kaldırmak için systemd servis dosyası rehberine bakabilirsiniz.
Sık yapılan hatalar
- Kullanıcı girdisini exec() içine birleştirmek:
exec('convert ' + dosyaAdi)gibi bir satır kabuk enjeksiyonuna açıktır.execFile()ya daspawn()ile argüman dizisi kullanın. - Çıktıyı okumadan spawn() kullanmak: Boru tamponu dolunca çocuk kilitlenir. Ya stdout'u okuyun ya
stdio: 'ignore'verin. - Sonucu exit olayında değerlendirmek:
exitgeldiğinde stdout'tan gelecek son parçalar henüz ulaşmamış olabilir. Çıktının tamamı lazımsacloseolayını bekleyin. - error olayını dinlememek: Komut bulunamazsa
ChildProcessbirerrorolayı yayar; dinleyici yoksa bu, yakalanmamış hata olarak süreci çökertir. - Sunucuda execSync() kullanmak: Her istekte çağrılan senkron bir alt süreç, o süre boyunca bütün istemcileri bekletir.
- Büyük çıktıda exec() kullanmak: Varsayılan 1 MB
maxBufferaşılınca süreç öldürülür. Büyük çıktı içinspawn()ile akış olarak okuyun. - Windows'ta .bat dosyasını execFile() ile çağırmak: Çalışmaz;
exec()ya dacmd.exe /ckullanın. - kill() çağrısının süreci bitirdiğini varsaymak: Belge,
killedözelliğinin yalnızca sinyalin başarıyla gönderildiğini gösterdiğini, sürecin sonlandığını garanti etmediğini söyler.
Sık Sorulan Sorular
exec ile execFile arasındaki fark nedir?
exec() bir kabuk açar ve komut dizesini o kabuğa verir; boru, yönlendirme ve joker karakter kullanabilirsiniz ama girdi enjeksiyonu riski taşır. execFile() varsayılan olarak kabuk açmadan programı doğrudan başlatır, argümanları dizi olarak alır ve biraz daha verimlidir. İkisi de çıktıyı tamponlar ve aynı geri çağırma imzasını kullanır.
Alt sürecin çıktısını async/await ile nasıl beklerim?
util.promisify(execFile) ya da util.promisify(exec) ile Promise döndüren sürümü alın ve await edin. spawn() için node:events modülündeki once(cocuk, 'close') fonksiyonunu bekleyebilirsiniz. Promise ve await temelleri için async/await yazısına bakın.
Bir alt süreci iptal etmenin doğru yolu nedir?
subprocess.kill() varsayılan olarak SIGTERM gönderir. Bir AbortController sinyalini signal seçeneğiyle verirseniz abort() çağrısı kill() gibi davranır, ama geri çağırmaya bir AbortError gelir. Belge, signal seçeneğini uzun ömürlü bir süreci kaynak temizliği amacıyla kapatmak için kullanmanın DEP0209 ile kullanımdan kaldırıldığını, iptal ve zaman aşımı için ise uygun olduğunu belirtir. Ayrıntılar AbortController yazısında.
child_process mi worker_threads mi kullanmalıyım?
Dış bir programı (ffmpeg, git, bir kabuk betiği) çalıştıracaksanız child_process tek seçenektir. JavaScript ile yazılmış CPU yoğun bir işi ana thread'den almak istiyorsanız worker_threads daha hafiftir ve SharedArrayBuffer ile bellek paylaşabilir; child_process ise her çocuk için ayrı bir süreç ve ayrı bellek demektir.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Node.js öğrenme rehberi · worker_threads kullanımı · Node.js stream nedir · ENOENT ve sistem hataları · cluster ve PM2