Ce face child_process.spawn
spawn pornește direct un program, cu argumentele date ca tablou, fără shell. Spre deosebire de exec, nu așteaptă finalul: copil.stdout și copil.stderr sunt stream-uri din care citești bucăți pe măsură ce programul afișează. Este varianta potrivită pentru comenzi lungi (compilări, descărcări) sau cu multă ieșire.
Procesul copil emite evenimentul "close" cu codul de ieșire, iar "error" dacă programul nu a putut fi pornit (de exemplu nu există). Poți scrie în copil.stdin, ca și cum utilizatorul ar tasta.
Opțiunea stdio: "inherit" leagă ieșirea copilului direct de terminalul tău (vezi culorile și progresul ca la rularea manuală). spawnSync este varianta sincronă și întoarce un obiect cu status, stdout, stderr. Pentru a porni tot Node.js, folosește process.execPath (calea executabilului curent) în loc de "node".
Parametri
| Parametru | Descriere |
|---|---|
comanda |
Programul de pornit ("git", process.execPath). |
argumente |
Tablou de șiruri, trimise exact, fără interpretare de shell. |
opțiuni.stdio |
"pipe" (implicit), "inherit" sau "ignore". |
opțiuni.cwd / env |
Directorul de lucru și variabilele de mediu ale copilului. |
opțiuni.shell |
true rulează prin shell (evită dacă argumentele vin din afară). |
Ce returnează
Un obiect ChildProcess (spawnSync: { status, stdout, stderr, ... }).
Exemple
Exemplul 1: Citire pe măsură ce apare ieșirea
Copilul este tot un script Node.js care afișează trei rânduri cu pauză. Părintele le primește pe rând.
import { spawn } from "node:child_process";
const script = `
for (const oras of ["Iași", "Cluj", "Arad"]) {
console.log("procesez " + oras);
await new Promise((r) => setTimeout(r, 20));
}
process.exitCode = 3;
`;
const copil = spawn(process.execPath, ["--input-type=module", "-e", script]);
copil.stdout.setEncoding("utf8");
copil.stdout.on("data", (bucata) => process.stdout.write("[copil] " + bucata));
copil.on("close", (cod) => console.log("Copilul a ieșit cu codul", cod));
Rezultat
[copil] procesez Iași
[copil] procesez Cluj
[copil] procesez Arad
Copilul a ieșit cu codul 3
Exemplul 2: Trimitere date pe stdin
import { spawn } from "node:child_process";
const sortare = spawn("sort", ["-r"]);
let rezultat = "";
sortare.stdout.on("data", (b) => (rezultat += b));
sortare.on("close", () => console.log(rezultat.trim().split("\n")));
sortare.stdin.write("Ana\nMaria\nIon\n");
sortare.stdin.end();
Rezultat
[ 'Maria', 'Ion', 'Ana' ]
Exemplul 3: spawnSync și program inexistent
import { spawnSync, spawn } from "node:child_process";
const r = spawnSync(process.execPath, ["-p", "6 * 7"], { encoding: "utf8" });
console.log(r.status, r.stdout.trim());
spawn("program-care-nu-exista").on("error", (e) => console.log(e.code));
Rezultat
0 42
ENOENT
Greșeli frecvente
- Dai toată comanda ca un singur șir:
spawn("git log --oneline")caută un program numit exact așa. Separă:spawn("git", ["log", "--oneline"]). - Nu asculți evenimentul
"error": dacă programul nu există, eroarea neprinsă oprește tot procesul părinte. - Citești
stdoutdoar la"exit": stream-urile pot avea încă date. Folosește"close", care vine după ce s-au închis stream-urile.
Comenzi înrudite
child_process.exec: Rulează o comandă în shell (ca în terminal) și primește la final tot textul afișat de ea.child_process.execFile: Rulează direct un program cu argumente separate, fără shell, și primește ieșirea la final. Varianta sigură a lui exec.stream.pipeline: Leagă stream-uri în lanț (citire → transformare → scriere), cu tratarea erorilor și închiderea tuturor la final.worker_threads (Worker): Rulează cod JavaScript în fire de execuție separate, ca un calcul greu să nu blocheze restul programului.