Skip to content

Kindprozess

[Stabil: 2 - Stabil]

Stabil: 2 Stabilität: 2 - Stabil

Quellcode: lib/child_process.js

Das Modul node:child_process bietet die Möglichkeit, Unterprozesse auf eine Art und Weise zu erzeugen, die popen(3) ähnlich, aber nicht identisch ist. Diese Fähigkeit wird hauptsächlich durch die Funktion child_process.spawn() bereitgestellt:

js
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}`);
});
js
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}`);
});

Standardmäßig werden Pipes für stdin, stdout und stderr zwischen dem übergeordneten Node.js-Prozess und dem erzeugten Unterprozess eingerichtet. Diese Pipes haben eine begrenzte (und plattformspezifische) Kapazität. Wenn der Unterprozess mehr Daten in stdout schreibt, als diese Kapazität zulässt, ohne dass die Ausgabe erfasst wird, blockiert der Unterprozess und wartet darauf, dass der Pipe-Puffer weitere Daten aufnimmt. Dies entspricht dem Verhalten von Pipes in der Shell. Verwenden Sie die Option { stdio: 'ignore' }, wenn die Ausgabe nicht verbraucht wird.

Die Befehlssuche erfolgt über die Umgebungsvariable options.env.PATH, wenn sich env im Objekt options befindet. Andernfalls wird process.env.PATH verwendet. Wenn options.env ohne PATH gesetzt ist, erfolgt die Suche unter Unix auf einem Standardsuchpfad von /usr/bin:/bin (siehe das Handbuch Ihres Betriebssystems für execvpe/execvp), unter Windows wird die Umgebungsvariable PATH des aktuellen Prozesses verwendet.

Unter Windows wird bei Umgebungsvariablen die Groß-/Kleinschreibung nicht beachtet. Node.js sortiert die env-Schlüssel lexikografisch und verwendet den ersten, der (ohne Beachtung der Groß-/Kleinschreibung) übereinstimmt. Nur der erste (in lexikografischer Reihenfolge) Eintrag wird an den Unterprozess übergeben. Dies kann unter Windows zu Problemen führen, wenn Objekte an die Option env übergeben werden, die mehrere Varianten desselben Schlüssels aufweisen, z. B. PATH und Path.

Die Methode child_process.spawn() erzeugt den Kindprozess asynchron, ohne die Node.js-Ereignisschleife zu blockieren. Die Funktion child_process.spawnSync() bietet eine äquivalente Funktionalität in einer synchronen Weise, die die Ereignisschleife blockiert, bis der erzeugte Prozess entweder beendet wird oder terminiert wird.

Der Einfachheit halber bietet das Modul node:child_process eine Handvoll synchroner und asynchroner Alternativen zu child_process.spawn() und child_process.spawnSync(). Jede dieser Alternativen wird auf Basis von child_process.spawn() oder child_process.spawnSync() implementiert.

Für bestimmte Anwendungsfälle, wie z. B. die Automatisierung von Shell-Skripten, können die synchronen Gegenstücke bequemer sein. In vielen Fällen können die synchronen Methoden jedoch erhebliche Auswirkungen auf die Leistung haben, da sie die Ereignisschleife blockieren, während erzeugte Prozesse abgeschlossen werden.

Asynchrone Prozesserstellung

Die Methoden child_process.spawn(), child_process.fork(), child_process.exec() und child_process.execFile() folgen alle dem idiomatischen asynchronen Programmiermuster, das typisch für andere Node.js-APIs ist.

Jede der Methoden gibt eine ChildProcess-Instanz zurück. Diese Objekte implementieren die Node.js EventEmitter-API, wodurch der übergeordnete Prozess Listener-Funktionen registrieren kann, die aufgerufen werden, wenn während des Lebenszyklus des untergeordneten Prozesses bestimmte Ereignisse auftreten.

Die Methoden child_process.exec() und child_process.execFile() ermöglichen zusätzlich die Angabe einer optionalen callback-Funktion, die aufgerufen wird, wenn der untergeordnete Prozess beendet wird.

Starten von .bat- und .cmd-Dateien unter Windows

Die Bedeutung der Unterscheidung zwischen child_process.exec() und child_process.execFile() kann je nach Plattform variieren. Auf Unix-artigen Betriebssystemen (Unix, Linux, macOS) kann child_process.execFile() effizienter sein, da es standardmäßig keine Shell startet. Unter Windows sind .bat- und .cmd-Dateien jedoch ohne Terminal nicht eigenständig ausführbar und können daher nicht mit child_process.execFile() gestartet werden. Bei der Ausführung unter Windows können .bat- und .cmd-Dateien mit child_process.spawn() mit der Option shell gestartet werden, mit child_process.exec() oder durch Starten von cmd.exe und Übergeben der .bat- oder .cmd-Datei als Argument (was die Option shell und child_process.exec() tun). In jedem Fall muss der Skriptdateiname in Anführungszeichen gesetzt werden, wenn er Leerzeichen enthält.

js
// ODER...
const { exec, spawn } = require('node:child_process');

exec('my.bat', (err, stdout, stderr) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(stdout);
});

// Skript mit Leerzeichen im Dateinamen:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
// oder:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
  // ...
});
js
// ODER...
import { exec, spawn } from 'node:child_process';

exec('my.bat', (err, stdout, stderr) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(stdout);
});

// Skript mit Leerzeichen im Dateinamen:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
// oder:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
  // ...
});

child_process.exec(command[, options][, callback])

[Verlauf]

VersionÄnderungen
v15.4.0Unterstützung für AbortSignal wurde hinzugefügt.
v16.4.0, v14.18.0Die Option cwd kann ein WHATWG URL-Objekt sein, das das file:-Protokoll verwendet.
v8.8.0Die Option windowsHide wird jetzt unterstützt.
v0.1.90Hinzugefügt in: v0.1.90
  • command <string> Der auszuführende Befehl mit durch Leerzeichen getrennten Argumenten.

  • options <Object>

    • cwd <string> | <URL> Aktuelles Arbeitsverzeichnis des Kindprozesses. Standard: process.cwd().
    • env <Object> Umgebungsschlüssel-Wert-Paare. Standard: process.env.
    • encoding <string> Standard: 'utf8'
    • shell <string> Shell, mit der der Befehl ausgeführt werden soll. Siehe Shell-Anforderungen und Standard-Windows-Shell. Standard: '/bin/sh' unter Unix, process.env.ComSpec unter Windows.
    • signal <AbortSignal> ermöglicht das Abbrechen des Kindprozesses mithilfe eines AbortSignals.
    • timeout <number> Standard: 0
    • maxBuffer <number> Größte Datenmenge in Bytes, die auf stdout oder stderr zulässig ist. Bei Überschreitung wird der Kindprozess beendet und die Ausgabe abgeschnitten. Siehe Caveat unter maxBuffer und Unicode. Standard: 1024 * 1024.
    • killSignal <string> | <integer> Standard: 'SIGTERM'
    • uid <number> Legt die Benutzeridentität des Prozesses fest (siehe setuid(2)).
    • gid <number> Legt die Gruppenidentität des Prozesses fest (siehe setgid(2)).
    • windowsHide <boolean> Blendet das Unterprozess-Konsolenfenster aus, das normalerweise auf Windows-Systemen erstellt wird. Standard: false.
  • callback <Function> wird mit der Ausgabe aufgerufen, wenn der Prozess beendet wird.

  • Gibt zurück: <ChildProcess>

Erzeugt eine Shell und führt dann den Befehl in dieser Shell aus, wobei die generierte Ausgabe gepuffert wird. Die an die Exec-Funktion übergebene command-Zeichenkette wird direkt von der Shell verarbeitet und Sonderzeichen (variieren je nach Shell) müssen entsprechend behandelt werden:

js
const { exec } = require('node:child_process');

exec('"/path/to/test file/test.sh" arg1 arg2');
// Doppelte Anführungszeichen werden verwendet, damit das Leerzeichen im Pfad nicht als
// Trennzeichen für mehrere Argumente interpretiert wird.

exec('echo "Die \\$HOME Variable ist $HOME"');
// Die $HOME Variable wird im ersten Fall maskiert, aber nicht im zweiten.
js
import { exec } from 'node:child_process';

exec('"/path/to/test file/test.sh" arg1 arg2');
// Doppelte Anführungszeichen werden verwendet, damit das Leerzeichen im Pfad nicht als
// Trennzeichen für mehrere Argumente interpretiert wird.

exec('echo "Die \\$HOME Variable ist $HOME"');
// Die $HOME Variable wird im ersten Fall maskiert, aber nicht im zweiten.

Übergeben Sie dieser Funktion niemals ungeprüfte Benutzereingaben. Jede Eingabe, die Shell-Metazeichen enthält, kann verwendet werden, um die Ausführung beliebiger Befehle auszulösen.

Wenn eine callback-Funktion bereitgestellt wird, wird sie mit den Argumenten (error, stdout, stderr) aufgerufen. Bei Erfolg ist error null. Im Fehlerfall ist error eine Instanz von Error. Die Eigenschaft error.code ist der Exit-Code des Prozesses. Konventionsgemäß deutet jeder andere Exit-Code als 0 auf einen Fehler hin. error.signal ist das Signal, das den Prozess beendet hat.

Die an den Callback übergebenen Argumente stdout und stderr enthalten die stdout- und stderr-Ausgabe des Kindprozesses. Standardmäßig dekodiert Node.js die Ausgabe als UTF-8 und übergibt Strings an den Callback. Die Option encoding kann verwendet werden, um die Zeichenkodierung anzugeben, die zum Dekodieren der stdout- und stderr-Ausgabe verwendet wird. Wenn encoding gleich 'buffer' oder eine nicht erkannte Zeichenkodierung ist, werden stattdessen Buffer-Objekte an den Callback übergeben.

js
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}`);
});
js
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}`);
});

Wenn timeout größer als 0 ist, sendet der übergeordnete Prozess das durch die Eigenschaft killSignal identifizierte Signal (Standard ist 'SIGTERM'), wenn der Kindprozess länger als timeout Millisekunden läuft.

Im Gegensatz zum POSIX-Systemaufruf exec(3) ersetzt child_process.exec() den vorhandenen Prozess nicht und verwendet eine Shell, um den Befehl auszuführen.

Wenn diese Methode als ihre util.promisify() -Version aufgerufen wird, gibt sie ein Promise für ein Object mit den Eigenschaften stdout und stderr zurück. Die zurückgegebene ChildProcess-Instanz ist als child-Eigenschaft an das Promise angehängt. Im Falle eines Fehlers (einschließlich eines Fehlers, der zu einem anderen Exit-Code als 0 führt) wird ein abgewiesenes Promise zurückgegeben, mit demselben error-Objekt, das im Callback angegeben ist, jedoch mit zwei zusätzlichen Eigenschaften stdout und stderr.

js
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();
js
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();

Wenn die Option signal aktiviert ist, ähnelt das Aufrufen von .abort() für den entsprechenden AbortController dem Aufrufen von .kill() für den Kindprozess, außer dass der an den Callback übergebene Fehler ein AbortError ist:

js
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();
js
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])

[Verlauf]

VersionÄnderungen
v16.4.0, v14.18.0Die Option cwd kann ein WHATWG URL-Objekt mit dem file:-Protokoll sein.
v15.4.0, v14.17.0AbortSignal-Unterstützung wurde hinzugefügt.
v8.8.0Die Option windowsHide wird jetzt unterstützt.
v0.1.91Hinzugefügt in: v0.1.91
  • file <string> Der Name oder Pfad der auszuführenden Datei.

  • args <string[]> Liste von String-Argumenten.

  • options <Object>

    • cwd <string> | <URL> Aktuelles Arbeitsverzeichnis des Kindprozesses.
    • env <Object> Umgebungsschlüssel-Wert-Paare. Standard: process.env.
    • encoding <string> Standard: 'utf8'
    • timeout <number> Standard: 0
    • maxBuffer <number> Größte Datenmenge in Byte, die auf stdout oder stderr zulässig ist. Wenn dieser Wert überschritten wird, wird der Kindprozess beendet und jegliche Ausgabe abgeschnitten. Siehe Caveat unter maxBuffer und Unicode. Standard: 1024 * 1024.
    • killSignal <string> | <integer> Standard: 'SIGTERM'
    • uid <number> Setzt die Benutzeridentität des Prozesses (siehe setuid(2)).
    • gid <number> Setzt die Gruppenidentität des Prozesses (siehe setgid(2)).
    • windowsHide <boolean> Verbirgt das Konsolenfenster des Subprozesses, das normalerweise auf Windows-Systemen erstellt würde. Standard: false.
    • windowsVerbatimArguments <boolean> Unter Windows erfolgt keine Maskierung oder Escaping von Argumenten. Wird unter Unix ignoriert. Standard: false.
    • shell <boolean> | <string> Wenn true, führt command innerhalb einer Shell aus. Verwendet '/bin/sh' unter Unix und process.env.ComSpec unter Windows. Eine andere Shell kann als String angegeben werden. Siehe Shell-Anforderungen und Standard-Windows-Shell. Standard: false (keine Shell).
    • signal <AbortSignal> ermöglicht das Abbrechen des Kindprozesses mit einem AbortSignal.
  • callback <Function> Wird mit der Ausgabe aufgerufen, wenn der Prozess beendet wird.

  • Gibt zurück: <ChildProcess>

Die Funktion child_process.execFile() ähnelt child_process.exec(), außer dass sie standardmäßig keine Shell erzeugt. Stattdessen wird die angegebene ausführbare Datei direkt als neuer Prozess erzeugt, was sie etwas effizienter macht als child_process.exec().

Die gleichen Optionen wie bei child_process.exec() werden unterstützt. Da keine Shell erzeugt wird, werden Verhaltensweisen wie I/O-Umleitung und File-Globbing nicht unterstützt.

js
const { execFile } = require('node:child_process');
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
  if (error) {
    throw error;
  }
  console.log(stdout);
});
js
import { execFile } from 'node:child_process';
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
  if (error) {
    throw error;
  }
  console.log(stdout);
});

Die an den Callback übergebenen Argumente stdout und stderr enthalten die stdout- und stderr-Ausgabe des Kindprozesses. Standardmäßig dekodiert Node.js die Ausgabe als UTF-8 und übergibt Strings an den Callback. Die Option encoding kann verwendet werden, um die Zeichenkodierung anzugeben, die zum Dekodieren der stdout- und stderr-Ausgabe verwendet wird. Wenn encoding 'buffer' oder eine nicht erkannte Zeichenkodierung ist, werden stattdessen Buffer-Objekte an den Callback übergeben.

Wenn diese Methode als ihre util.promisify()ed-Version aufgerufen wird, gibt sie ein Promise für ein Object mit stdout- und stderr-Eigenschaften zurück. Die zurückgegebene ChildProcess-Instanz ist dem Promise als child-Eigenschaft angehängt. Im Falle eines Fehlers (einschließlich jedes Fehlers, der zu einem anderen Exit-Code als 0 führt) wird ein abgewiesenes Promise zurückgegeben, mit demselben error-Objekt, das im Callback angegeben ist, jedoch mit zwei zusätzlichen Eigenschaften stdout und stderr.

js
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();
js
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();

Wenn die Option shell aktiviert ist, übergeben Sie keine unbereinigten Benutzereingaben an diese Funktion. Jede Eingabe, die Shell-Metazeichen enthält, kann verwendet werden, um die Ausführung von beliebigem Code auszulösen.

Wenn die Option signal aktiviert ist, ist der Aufruf von .abort() für den entsprechenden AbortController ähnlich wie der Aufruf von .kill() für den Kindprozess, außer dass der an den Callback übergebene Fehler ein AbortError ist:

js
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();
js
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])

[Historie]

VersionÄnderungen
v17.4.0, v16.14.0Der Parameter modulePath kann ein WHATWG URL-Objekt mit dem Protokoll file: sein.
v16.4.0, v14.18.0Die Option cwd kann ein WHATWG URL-Objekt mit dem Protokoll file: sein.
v15.13.0, v14.18.0Timeout wurde hinzugefügt.
v15.11.0, v14.18.0KillSignal für AbortSignal wurde hinzugefügt.
v15.6.0, v14.17.0AbortSignal-Unterstützung wurde hinzugefügt.
v13.2.0, v12.16.0Die Option serialization wird jetzt unterstützt.
v8.0.0Die Option stdio kann jetzt eine Zeichenkette sein.
v6.4.0Die Option stdio wird jetzt unterstützt.
v0.5.0Hinzugefügt in: v0.5.0
  • modulePath <string> | <URL> Das Modul, das im Kindprozess ausgeführt werden soll.

  • args <string[]> Liste von Zeichenkettenargumenten.

  • options <Object>

    • cwd <string> | <URL> Aktuelles Arbeitsverzeichnis des Kindprozesses.
    • detached <boolean> Bereitet den Kindprozess vor, unabhängig von seinem Elternprozess zu laufen. Das spezifische Verhalten hängt von der Plattform ab, siehe options.detached).
    • env <Object> Umgebungsschlüssel-Wert-Paare. Standard: process.env.
    • execPath <string> Ausführbare Datei, die zum Erstellen des Kindprozesses verwendet wird.
    • execArgv <string[]> Liste von Zeichenkettenargumenten, die an die ausführbare Datei übergeben werden. Standard: process.execArgv.
    • gid <number> Setzt die Gruppenidentität des Prozesses (siehe setgid(2)).
    • serialization <string> Gibt die Art der Serialisierung an, die zum Senden von Nachrichten zwischen Prozessen verwendet wird. Mögliche Werte sind 'json' und 'advanced'. Siehe Erweiterte Serialisierung für weitere Details. Standard: 'json'.
    • signal <AbortSignal> Erlaubt das Schließen des Kindprozesses mit einem AbortSignal.
    • killSignal <string> | <integer> Der Signalwert, der verwendet werden soll, wenn der erzeugte Prozess durch Timeout oder Abort-Signal beendet wird. Standard: 'SIGTERM'.
    • silent <boolean> Wenn true, werden stdin, stdout und stderr des Kindprozesses zum Elternprozess geleitet, andernfalls werden sie vom Elternprozess übernommen, siehe die Optionen 'pipe' und 'inherit' für child_process.spawn()'s stdio für weitere Details. Standard: false.
    • stdio <Array> | <string> Siehe child_process.spawn()'s stdio. Wenn diese Option angegeben wird, überschreibt sie silent. Wenn die Array-Variante verwendet wird, muss sie genau ein Element mit dem Wert 'ipc' enthalten, sonst wird ein Fehler geworfen. Zum Beispiel [0, 1, 2, 'ipc'].
    • uid <number> Setzt die Benutzeridentität des Prozesses (siehe setuid(2)).
    • windowsVerbatimArguments <boolean> Unter Windows werden Argumente weder in Anführungszeichen gesetzt noch maskiert. Wird unter Unix ignoriert. Standard: false.
    • timeout <number> In Millisekunden die maximale Zeit, die der Prozess laufen darf. Standard: undefined.
  • Gibt zurück: <ChildProcess>

Die Methode child_process.fork() ist ein Sonderfall von child_process.spawn(), der speziell zum Starten neuer Node.js-Prozesse verwendet wird. Wie child_process.spawn() wird ein ChildProcess-Objekt zurückgegeben. Der zurückgegebene ChildProcess verfügt über einen zusätzlichen eingebauten Kommunikationskanal, der es ermöglicht, Nachrichten zwischen Eltern- und Kindprozess hin und her zu senden. Siehe subprocess.send() für Details.

Beachten Sie, dass gestartete Node.js-Kindprozesse unabhängig vom Elternprozess sind, mit Ausnahme des IPC-Kommunikationskanals, der zwischen den beiden eingerichtet wird. Jeder Prozess hat seinen eigenen Speicher mit eigenen V8-Instanzen. Aufgrund der zusätzlichen erforderlichen Ressourcenzuweisungen wird das Starten einer großen Anzahl von Node.js-Kindprozessen nicht empfohlen.

Standardmäßig startet child_process.fork() neue Node.js-Instanzen mit dem process.execPath des Elternprozesses. Die Eigenschaft execPath im options-Objekt ermöglicht die Verwendung eines alternativen Ausführungspfads.

Node.js-Prozesse, die mit einem benutzerdefinierten execPath gestartet werden, kommunizieren mit dem Elternprozess über den Dateideskriptor (fd), der über die Umgebungsvariable NODE_CHANNEL_FD im Kindprozess identifiziert wird.

Im Gegensatz zum POSIX-Systemaufruf fork(2) klont child_process.fork() nicht den aktuellen Prozess.

Die in child_process.spawn() verfügbare Option shell wird von child_process.fork() nicht unterstützt und wird ignoriert, wenn sie gesetzt ist.

Wenn die Option signal aktiviert ist, ist der Aufruf von .abort() auf dem entsprechenden AbortController ähnlich dem Aufruf von .kill() auf dem Kindprozess, außer dass der an den Callback übergebene Fehler ein AbortError ist:

js
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) => {
    // This will be called with err being an AbortError if the controller aborts
  });
  controller.abort(); // Stops the child process
}
js
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) => {
    // This will be called with err being an AbortError if the controller aborts
  });
  controller.abort(); // Stops the child process
}

child_process.spawn(command[, args][, options])

[Verlauf]

VersionÄnderungen
v16.4.0, v14.18.0Die Option cwd kann ein WHATWG URL-Objekt mit dem file:-Protokoll sein.
v15.13.0, v14.18.0Timeout wurde hinzugefügt.
v15.11.0, v14.18.0killSignal für AbortSignal wurde hinzugefügt.
v15.5.0, v14.17.0AbortSignal-Unterstützung wurde hinzugefügt.
v13.2.0, v12.16.0Die Option serialization wird jetzt unterstützt.
v8.8.0Die Option windowsHide wird jetzt unterstützt.
v6.4.0Die Option argv0 wird jetzt unterstützt.
v5.7.0Die Option shell wird jetzt unterstützt.
v0.1.90Hinzugefügt in: v0.1.90
  • command <string> Der auszuführende Befehl.

  • args <string[]> Liste der Zeichenkettenargumente.

  • options <Object>

    • cwd <string> | <URL> Aktuelles Arbeitsverzeichnis des Kindprozesses.
    • env <Object> Umgebungsvariablen-Schlüssel-Wert-Paare. Standard: process.env.
    • argv0 <string> Legt explizit den Wert von argv[0] fest, der an den Kindprozess gesendet wird. Dieser wird auf command gesetzt, wenn er nicht angegeben ist.
    • stdio <Array> | <string> Die stdio-Konfiguration des Kindprozesses (siehe options.stdio).
    • detached <boolean> Bereitet den Kindprozess vor, unabhängig von seinem Elternprozess zu laufen. Das spezifische Verhalten hängt von der Plattform ab, siehe options.detached).
    • uid <number> Setzt die Benutzeridentität des Prozesses (siehe setuid(2)).
    • gid <number> Setzt die Gruppenidentität des Prozesses (siehe setgid(2)).
    • serialization <string> Gibt die Art der Serialisierung an, die zum Senden von Nachrichten zwischen Prozessen verwendet wird. Mögliche Werte sind 'json' und 'advanced'. Weitere Informationen finden Sie unter Erweiterte Serialisierung. Standard: 'json'.
    • shell <boolean> | <string> Wenn true, führt command innerhalb einer Shell aus. Verwendet '/bin/sh' unter Unix und process.env.ComSpec unter Windows. Eine andere Shell kann als String angegeben werden. Siehe Shell-Anforderungen und Standard-Windows-Shell. Standard: false (keine Shell).
    • windowsVerbatimArguments <boolean> Unter Windows werden Argumente weder in Anführungszeichen gesetzt noch maskiert. Wird unter Unix ignoriert. Dies wird automatisch auf true gesetzt, wenn shell angegeben ist und CMD ist. Standard: false.
    • windowsHide <boolean> Blendet das Subprozess-Konsolenfenster aus, das normalerweise unter Windows-Systemen erstellt würde. Standard: false.
    • signal <AbortSignal> ermöglicht das Abbrechen des Kindprozesses mit einem AbortSignal.
    • timeout <number> In Millisekunden die maximale Zeit, die der Prozess laufen darf. Standard: undefined.
    • killSignal <string> | <integer> Der Signalwert, der verwendet werden soll, wenn der erzeugte Prozess durch Timeout oder Abbruchsignal beendet wird. Standard: 'SIGTERM'.
  • Gibt zurück: <ChildProcess>

Die Methode child_process.spawn() erzeugt einen neuen Prozess mit dem gegebenen command, mit Kommandozeilenargumenten in args. Wenn ausgelassen, ist args standardmäßig ein leeres Array.

Wenn die Option shell aktiviert ist, übergeben Sie dieser Funktion keine ungeprüften Benutzereingaben. Jede Eingabe, die Shell-Metazeichen enthält, kann verwendet werden, um die Ausführung beliebiger Befehle auszulösen.

Ein drittes Argument kann verwendet werden, um zusätzliche Optionen anzugeben, mit diesen Standardwerten:

js
const defaults = {
  cwd: undefined,
  env: process.env,
};

Verwenden Sie cwd, um das Arbeitsverzeichnis anzugeben, aus dem der Prozess erzeugt wird. Wenn nicht angegeben, wird standardmäßig das aktuelle Arbeitsverzeichnis geerbt. Wenn angegeben, aber der Pfad nicht existiert, gibt der Kindprozess einen ENOENT-Fehler aus und beendet sich sofort. ENOENT wird auch ausgegeben, wenn der Befehl nicht existiert.

Verwenden Sie env, um Umgebungsvariablen anzugeben, die für den neuen Prozess sichtbar sind, der Standardwert ist process.env.

undefined-Werte in env werden ignoriert.

Beispiel für die Ausführung von ls -lh /usr, wobei stdout, stderr und der Exit-Code erfasst werden:

js
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}`);
});
js
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}`);
});

Beispiel: Eine sehr aufwändige Art, ps ax | grep ssh auszuführen

js
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}`);
  }
});
js
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}`);
  }
});

Beispiel für die Prüfung auf fehlgeschlagenes spawn:

js
const { spawn } = require('node:child_process');
const subprocess = spawn('bad_command');

subprocess.on('error', (err) => {
  console.error('Failed to start subprocess.');
});
js
import { spawn } from 'node:child_process';
const subprocess = spawn('bad_command');

subprocess.on('error', (err) => {
  console.error('Failed to start subprocess.');
});

Bestimmte Plattformen (macOS, Linux) verwenden den Wert von argv[0] für den Prozesstitel, während andere (Windows, SunOS) command verwenden.

Node.js überschreibt argv[0] beim Start mit process.execPath, sodass process.argv[0] in einem Node.js-Kindprozess nicht mit dem argv0-Parameter übereinstimmt, der von spawn vom Elternprozess übergeben wird. Rufen Sie ihn stattdessen mit der Eigenschaft process.argv0 ab.

Wenn die Option signal aktiviert ist, ist das Aufrufen von .abort() für den entsprechenden AbortController ähnlich wie das Aufrufen von .kill() für den Kindprozess, mit der Ausnahme, dass der an den Callback übergebene Fehler ein AbortError ist:

js
const { spawn } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const grep = spawn('grep', ['ssh'], { signal });
grep.on('error', (err) => {
  // Dies wird aufgerufen, wobei err ein AbortError ist, wenn der Controller abbricht
});
controller.abort(); // Stoppt den Kindprozess
js
import { spawn } from 'node:child_process';
const controller = new AbortController();
const { signal } = controller;
const grep = spawn('grep', ['ssh'], { signal });
grep.on('error', (err) => {
  // Dies wird aufgerufen, wobei err ein AbortError ist, wenn der Controller abbricht
});
controller.abort(); // Stoppt den Kindprozess

options.detached

Hinzugefügt in: v0.7.10

Unter Windows ermöglicht die Einstellung von options.detached auf true, dass der Kindprozess nach dem Beenden des Elternprozesses weiterläuft. Der Kindprozess erhält ein eigenes Konsolenfenster. Sobald diese Option für einen Kindprozess aktiviert ist, kann sie nicht mehr deaktiviert werden.

Auf Nicht-Windows-Plattformen wird der Kindprozess, wenn options.detached auf true gesetzt ist, zum Leiter einer neuen Prozessgruppe und Sitzung gemacht. Kindprozesse können nach dem Beenden des Elternprozesses weiterlaufen, unabhängig davon, ob sie abgetrennt sind oder nicht. Siehe setsid(2) für weitere Informationen.

Standardmäßig wartet der Elternprozess darauf, dass der abgetrennte Kindprozess beendet wird. Um zu verhindern, dass der Elternprozess auf die Beendigung eines bestimmten subprocess wartet, verwenden Sie die Methode subprocess.unref(). Dadurch wird die Ereignisschleife des Elternprozesses den Kindprozess nicht in ihre Referenzzählung aufnehmen, wodurch der Elternprozess unabhängig vom Kindprozess beendet werden kann, es sei denn, es besteht ein etablierter IPC-Kanal zwischen dem Kind- und dem Elternprozess.

Wenn die Option detached verwendet wird, um einen langlaufenden Prozess zu starten, bleibt der Prozess nach dem Beenden des Elternprozesses nicht im Hintergrund aktiv, es sei denn, er wird mit einer stdio-Konfiguration versehen, die nicht mit dem Elternprozess verbunden ist. Wenn das stdio des Elternprozesses geerbt wird, bleibt der Kindprozess mit dem steuernden Terminal verbunden.

Beispiel für einen langlaufenden Prozess durch Abtrennen und Ignorieren der stdio-Dateideskriptoren des Elternprozesses, um die Beendigung des Elternprozesses zu ignorieren:

js
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();
js
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();

Alternativ kann man die Ausgabe des Kindprozesses in Dateien umleiten:

js
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();
js
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

[Historie]

VersionÄnderungen
v15.6.0, v14.18.0Der overlapped-Stdio-Flag wurde hinzugefügt.
v3.3.1Der Wert 0 wird jetzt als Dateideskriptor akzeptiert.
v0.7.10Hinzugefügt in: v0.7.10

Die Option options.stdio wird verwendet, um die Pipes zu konfigurieren, die zwischen dem Eltern- und Kindprozess eingerichtet werden. Standardmäßig werden die stdin-, stdout- und stderr-Kanäle des Kindprozesses zu den entsprechenden subprocess.stdin-, subprocess.stdout- und subprocess.stderr-Streams auf dem ChildProcess-Objekt umgeleitet. Dies entspricht der Einstellung von options.stdio auf ['pipe', 'pipe', 'pipe'].

Der Einfachheit halber kann options.stdio eine der folgenden Zeichenketten sein:

  • 'pipe': entspricht ['pipe', 'pipe', 'pipe'] (der Standard)
  • 'overlapped': entspricht ['overlapped', 'overlapped', 'overlapped']
  • 'ignore': entspricht ['ignore', 'ignore', 'ignore']
  • 'inherit': entspricht ['inherit', 'inherit', 'inherit'] oder [0, 1, 2]

Andernfalls ist der Wert von options.stdio ein Array, bei dem jeder Index einem Filedeskriptor (fd) im Kindprozess entspricht. Die Filedeskriptoren 0, 1 und 2 entsprechen stdin, stdout bzw. stderr. Zusätzliche Filedeskriptoren können angegeben werden, um zusätzliche Pipes zwischen dem Eltern- und Kindprozess zu erstellen. Der Wert ist einer der folgenden:

js
const { spawn } = require('node:child_process');
const process = require('node:process');

// Kindprozess verwendet die stdios des Elternprozesses.
spawn('prg', [], { stdio: 'inherit' });

// Kindprozess nur mit gemeinsam genutztem stderr starten.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });

// Öffne einen zusätzlichen fd=4, um mit Programmen zu interagieren,
// die eine Startd-ähnliche Schnittstelle darstellen.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });
js
import { spawn } from 'node:child_process';
import process from 'node:process';

// Kindprozess verwendet die stdios des Elternprozesses.
spawn('prg', [], { stdio: 'inherit' });

// Kindprozess nur mit gemeinsam genutztem stderr starten.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });

// Öffne einen zusätzlichen fd=4, um mit Programmen zu interagieren,
// die eine Startd-ähnliche Schnittstelle darstellen.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });

Es ist erwähnenswert, dass, wenn ein IPC-Kanal zwischen den Eltern- und Kindprozessen eingerichtet wird und der Kindprozess eine Node.js-Instanz ist, der Kindprozess mit dem IPC-Kanal dereferenziert (mit unref()) gestartet wird, bis der Kindprozess einen Ereignishandler für das 'disconnect'-Ereignis oder das 'message'-Ereignis registriert. Dies ermöglicht es dem Kindprozess, normal zu beenden, ohne dass der Prozess durch den offenen IPC-Kanal offen gehalten wird. Siehe auch: child_process.exec() und child_process.fork().

Synchrone Prozesserstellung

Die Methoden child_process.spawnSync(), child_process.execSync() und child_process.execFileSync() sind synchron und blockieren die Node.js Event-Loop, wodurch die Ausführung von zusätzlichem Code angehalten wird, bis der gestartete Prozess beendet ist.

Blockierende Aufrufe wie diese sind meistens nützlich, um allgemeine Skripting-Aufgaben zu vereinfachen und das Laden/Verarbeiten von Anwendungskonfigurationen beim Start zu vereinfachen.

child_process.execFileSync(file[, args][, options])

[Verlauf]

VersionÄnderungen
v16.4.0, v14.18.0Die cwd-Option kann ein WHATWG URL-Objekt mit dem file:-Protokoll sein.
v10.10.0Die input-Option kann jetzt ein beliebiges TypedArray oder ein DataView sein.
v8.8.0Die windowsHide-Option wird jetzt unterstützt.
v8.0.0Die input-Option kann jetzt ein Uint8Array sein.
v6.2.1, v4.5.0Die encoding-Option kann jetzt explizit auf buffer gesetzt werden.
v0.11.12Hinzugefügt in: v0.11.12
  • file <string> Der Name oder Pfad der ausführbaren Datei, die ausgeführt werden soll.

  • args <string[]> Liste der Zeichenfolgenargumente.

  • options <Object>

    • cwd <string> | <URL> Aktuelles Arbeitsverzeichnis des Kindprozesses.
    • input <string> | <Buffer> | <TypedArray> | <DataView> Der Wert, der als stdin an den gestarteten Prozess übergeben wird. Wenn stdio[0] auf 'pipe' gesetzt ist, überschreibt die Angabe dieses Wertes stdio[0].
    • stdio <string> | <Array> Stdio-Konfiguration des Kindes. Siehe child_process.spawn()'s stdio. stderr wird standardmäßig an den stderr des Elternprozesses ausgegeben, es sei denn, stdio ist angegeben. Standard: 'pipe'.
    • env <Object> Umgebungsschlüssel-Wert-Paare. Standard: process.env.
    • uid <number> Setzt die Benutzeridentität des Prozesses (siehe setuid(2)).
    • gid <number> Setzt die Gruppenidentität des Prozesses (siehe setgid(2)).
    • timeout <number> In Millisekunden die maximale Zeit, die der Prozess laufen darf. Standard: undefined.
    • killSignal <string> | <integer> Der Signalwert, der verwendet werden soll, wenn der gestartete Prozess beendet wird. Standard: 'SIGTERM'.
    • maxBuffer <number> Größte Datenmenge in Bytes, die auf stdout oder stderr zulässig ist. Wenn dies überschritten wird, wird der Kindprozess beendet. Siehe Caveat unter maxBuffer und Unicode. Standard: 1024 * 1024.
    • encoding <string> Die Kodierung, die für alle stdio-Eingaben und -Ausgaben verwendet wird. Standard: 'buffer'.
    • windowsHide <boolean> Blendet das Konsolenfenster des Subprozesses aus, das normalerweise auf Windows-Systemen erstellt wird. Standard: false.
    • shell <boolean> | <string> Wenn true, führt command innerhalb einer Shell aus. Verwendet '/bin/sh' unter Unix und process.env.ComSpec unter Windows. Eine andere Shell kann als Zeichenkette angegeben werden. Siehe Shell-Anforderungen und Standard-Windows-Shell. Standard: false (keine Shell).
  • Gibt zurück: <Buffer> | <string> Die stdout-Ausgabe des Befehls.

Die Methode child_process.execFileSync() ist im Allgemeinen identisch mit child_process.execFile() mit der Ausnahme, dass die Methode erst zurückkehrt, wenn der Kindprozess vollständig geschlossen wurde. Wenn ein Timeout aufgetreten ist und killSignal gesendet wird, kehrt die Methode erst zurück, wenn der Prozess vollständig beendet wurde.

Wenn der Kindprozess das SIGTERM-Signal abfängt und behandelt und nicht beendet wird, wartet der Elternprozess weiterhin, bis der Kindprozess beendet wurde.

Wenn der Prozess eine Zeitüberschreitung hat oder einen Exit-Code ungleich Null hat, wirft diese Methode einen Error, der das vollständige Ergebnis von zugrunde liegenden child_process.spawnSync() enthält.

Wenn die Option shell aktiviert ist, übergeben Sie dieser Funktion keine ungeprüften Benutzereingaben. Alle Eingaben, die Shell-Metazeichen enthalten, können verwendet werden, um die Ausführung von beliebigem Code auszulösen.

js
const { execFileSync } = require('node:child_process');

try {
  const stdout = execFileSync('my-script.sh', ['my-arg'], {
    // Capture stdout and stderr from child process. Overrides the
    // default behavior of streaming child stderr to the parent stderr
    stdio: 'pipe',

    // Use utf8 encoding for stdio pipes
    encoding: 'utf8',
  });

  console.log(stdout);
} catch (err) {
  if (err.code) {
    // Spawning child process failed
    console.error(err.code);
  } else {
    // Child was spawned but exited with non-zero exit code
    // Error contains any stdout and stderr from the child
    const { stdout, stderr } = err;

    console.error({ stdout, stderr });
  }
}
js
import { execFileSync } from 'node:child_process';

try {
  const stdout = execFileSync('my-script.sh', ['my-arg'], {
    // Capture stdout and stderr from child process. Overrides the
    // default behavior of streaming child stderr to the parent stderr
    stdio: 'pipe',

    // Use utf8 encoding for stdio pipes
    encoding: 'utf8',
  });

  console.log(stdout);
} catch (err) {
  if (err.code) {
    // Spawning child process failed
    console.error(err.code);
  } else {
    // Child was spawned but exited with non-zero exit code
    // Error contains any stdout and stderr from the child
    const { stdout, stderr } = err;

    console.error({ stdout, stderr });
  }
}

child_process.execSync(command[, options])

[Verlauf]

VersionÄnderungen
v16.4.0, v14.18.0Die Option cwd kann ein WHATWG URL-Objekt mit dem file:-Protokoll sein.
v10.10.0Die Option input kann nun ein beliebiges TypedArray oder ein DataView sein.
v8.8.0Die Option windowsHide wird jetzt unterstützt.
v8.0.0Die Option input kann nun ein Uint8Array sein.
v0.11.12Hinzugefügt in: v0.11.12
  • command <string> Der auszuführende Befehl.

  • options <Object>

    • cwd <string> | <URL> Aktuelles Arbeitsverzeichnis des Kindprozesses.
    • input <string> | <Buffer> | <TypedArray> | <DataView> Der Wert, der als stdin an den erzeugten Prozess übergeben wird. Wenn stdio[0] auf 'pipe' gesetzt ist, überschreibt die Angabe dieses Wertes stdio[0].
    • stdio <string> | <Array> Die stdio-Konfiguration des Kindes. Siehe child_process.spawn()'s stdio. stderr wird standardmäßig an das stderr des Elternprozesses ausgegeben, es sei denn, stdio ist angegeben. Standard: 'pipe'.
    • env <Object> Umgebungsschlüssel-Wert-Paare. Standard: process.env.
    • shell <string> Shell, mit der der Befehl ausgeführt werden soll. Siehe Shell-Anforderungen und Standard-Windows-Shell. Standard: '/bin/sh' auf Unix, process.env.ComSpec auf Windows.
    • uid <number> Setzt die Benutzerkennung des Prozesses. (Siehe setuid(2)).
    • gid <number> Setzt die Gruppenkennung des Prozesses. (Siehe setgid(2)).
    • timeout <number> In Millisekunden die maximale Zeitspanne, die der Prozess laufen darf. Standard: undefined.
    • killSignal <string> | <integer> Das Signal, das verwendet werden soll, wenn der erzeugte Prozess beendet wird. Standard: 'SIGTERM'.
    • maxBuffer <number> Die größte Datenmenge in Bytes, die in stdout oder stderr zulässig ist. Wenn diese überschritten wird, wird der Kindprozess beendet und jegliche Ausgabe wird abgeschnitten. Siehe den Hinweis unter maxBuffer und Unicode. Standard: 1024 * 1024.
    • encoding <string> Die für alle stdio-Ein- und Ausgaben verwendete Kodierung. Standard: 'buffer'.
    • windowsHide <boolean> Verbirgt das Konsolenfenster des Subprozesses, das normalerweise auf Windows-Systemen erstellt wird. Standard: false.
  • Gibt zurück: <Buffer> | <string> Die stdout-Ausgabe des Befehls.

Die Methode child_process.execSync() ist im Allgemeinen identisch mit child_process.exec() mit der Ausnahme, dass die Methode erst zurückkehrt, wenn der Kindprozess vollständig beendet wurde. Wenn ein Timeout aufgetreten ist und killSignal gesendet wird, kehrt die Methode erst zurück, wenn der Prozess vollständig beendet wurde. Wenn der Kindprozess das SIGTERM-Signal abfängt und behandelt und nicht beendet wird, wartet der Elternprozess, bis der Kindprozess beendet wurde.

Wenn der Prozess ein Timeout hat oder einen Exit-Code ungleich Null hat, wirft diese Methode eine Ausnahme. Das Error-Objekt enthält das gesamte Ergebnis von child_process.spawnSync().

Geben Sie niemals ungeprüfte Benutzereingaben an diese Funktion weiter. Jede Eingabe, die Shell-Metazeichen enthält, kann verwendet werden, um die Ausführung beliebiger Befehle auszulösen.

child_process.spawnSync(command[, args][, options])

[Verlauf]

VersionÄnderungen
v16.4.0, v14.18.0Die Option cwd kann ein WHATWG URL-Objekt mit dem file:-Protokoll sein.
v10.10.0Die Option input kann nun ein beliebiges TypedArray oder eine DataView sein.
v8.8.0Die Option windowsHide wird jetzt unterstützt.
v8.0.0Die Option input kann nun ein Uint8Array sein.
v5.7.0Die Option shell wird jetzt unterstützt.
v6.2.1, v4.5.0Die Option encoding kann jetzt explizit auf buffer gesetzt werden.
v0.11.12Hinzugefügt in: v0.11.12
  • command <string> Der auszuführende Befehl.

  • args <string[]> Liste von String-Argumenten.

  • options <Object>

    • cwd <string> | <URL> Aktuelles Arbeitsverzeichnis des Kindprozesses.
    • input <string> | <Buffer> | <TypedArray> | <DataView> Der Wert, der als stdin an den erzeugten Prozess übergeben wird. Wenn stdio[0] auf 'pipe' gesetzt ist, überschreibt die Angabe dieses Werts stdio[0].
    • argv0 <string> Legt explizit den Wert von argv[0] fest, der an den Kindprozess gesendet wird. Dieser wird auf command gesetzt, wenn er nicht angegeben ist.
    • stdio <string> | <Array> Stdio-Konfiguration des Kindprozesses. Siehe child_process.spawn()'s stdio. Standard: 'pipe'.
    • env <Object> Umgebungsschlüssel-Wert-Paare. Standard: process.env.
    • uid <number> Setzt die Benutzeridentität des Prozesses (siehe setuid(2)).
    • gid <number> Setzt die Gruppenidentität des Prozesses (siehe setgid(2)).
    • timeout <number> In Millisekunden die maximale Zeitspanne, die der Prozess laufen darf. Standard: undefined.
    • killSignal <string> | <integer> Das Signal, das verwendet werden soll, wenn der erzeugte Prozess beendet wird. Standard: 'SIGTERM'.
    • maxBuffer <number> Die größte Datenmenge in Bytes, die in stdout oder stderr zulässig ist. Wenn dieser Wert überschritten wird, wird der Kindprozess beendet und die Ausgabe wird abgeschnitten. Siehe Caveat unter maxBuffer und Unicode. Standard: 1024 * 1024.
    • encoding <string> Die Kodierung, die für alle stdio-Eingaben und -Ausgaben verwendet wird. Standard: 'buffer'.
    • shell <boolean> | <string> Wenn true, wird command innerhalb einer Shell ausgeführt. Verwendet '/bin/sh' unter Unix und process.env.ComSpec unter Windows. Eine andere Shell kann als String angegeben werden. Siehe Shell-Anforderungen und Standard-Windows-Shell. Standard: false (keine Shell).
    • windowsVerbatimArguments <boolean> Unter Windows werden keine Argumente in Anführungszeichen gesetzt oder maskiert. Wird unter Unix ignoriert. Dies wird automatisch auf true gesetzt, wenn shell angegeben ist und CMD ist. Standard: false.
    • windowsHide <boolean> Blendet das Konsolenfenster des Subprozesses aus, das normalerweise auf Windows-Systemen erstellt würde. Standard: false.
  • Gibt zurück: <Object>

    • pid <number> Pid des Kindprozesses.
    • output <Array> Array der Ergebnisse der stdio-Ausgabe.
    • stdout <Buffer> | <string> Der Inhalt von output[1].
    • stderr <Buffer> | <string> Der Inhalt von output[2].
    • status <number> | <null> Der Exit-Code des Subprozesses oder null, wenn der Subprozess aufgrund eines Signals beendet wurde.
    • signal <string> | <null> Das Signal, das zum Beenden des Subprozesses verwendet wurde, oder null, wenn der Subprozess nicht aufgrund eines Signals beendet wurde.
    • error <Error> Das Fehlerobjekt, wenn der Kindprozess fehlgeschlagen ist oder ein Timeout aufgetreten ist.

Die Methode child_process.spawnSync() ist im Allgemeinen identisch mit child_process.spawn(), mit der Ausnahme, dass die Funktion erst zurückkehrt, wenn der Kindprozess vollständig geschlossen wurde. Wenn ein Timeout aufgetreten ist und killSignal gesendet wird, kehrt die Methode erst zurück, wenn der Prozess vollständig beendet wurde. Wenn der Prozess das Signal SIGTERM abfängt und verarbeitet und nicht beendet wird, wartet der Elternprozess, bis der Kindprozess beendet wurde.

Wenn die Option shell aktiviert ist, geben Sie dieser Funktion keine ungeprüften Benutzereingaben. Jede Eingabe, die Shell-Metazeichen enthält, kann verwendet werden, um die Ausführung beliebiger Befehle auszulösen.

Klasse: ChildProcess

Hinzugefügt in: v2.2.0

Instanzen von ChildProcess repräsentieren erzeugte Kindprozesse.

Es ist nicht vorgesehen, Instanzen von ChildProcess direkt zu erstellen. Verwenden Sie stattdessen die Methoden child_process.spawn(), child_process.exec(), child_process.execFile() oder child_process.fork(), um Instanzen von ChildProcess zu erstellen.

Ereignis: 'close'

Hinzugefügt in: v0.7.7

  • code <number> Der Exit-Code, wenn der Kindprozess von selbst beendet wurde.
  • signal <string> Das Signal, durch das der Kindprozess beendet wurde.

Das Ereignis 'close' wird ausgelöst, nachdem ein Prozess beendet wurde und die stdio-Streams eines Kindprozesses geschlossen wurden. Dies unterscheidet sich vom Ereignis 'exit', da mehrere Prozesse möglicherweise dieselben stdio-Streams verwenden. Das Ereignis 'close' wird immer ausgelöst, nachdem 'exit' bereits ausgelöst wurde, oder 'error', wenn der Kindprozess nicht gestartet werden konnte.

js
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}`);
});
js
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}`);
});

Ereignis: 'disconnect'

Hinzugefügt in: v0.7.2

Das Ereignis 'disconnect' wird ausgelöst, nachdem die Methode subprocess.disconnect() im Elternprozess oder process.disconnect() im Kindprozess aufgerufen wurde. Nach dem Trennen ist es nicht mehr möglich, Nachrichten zu senden oder zu empfangen, und die Eigenschaft subprocess.connected ist false.

Ereignis: 'error'

Das Ereignis 'error' wird immer dann ausgelöst, wenn:

  • Der Prozess nicht gestartet werden konnte.
  • Der Prozess nicht beendet werden konnte.
  • Das Senden einer Nachricht an den Kindprozess fehlgeschlagen ist.
  • Der Kindprozess über die Option signal abgebrochen wurde.

Das Ereignis 'exit' kann nach dem Auftreten eines Fehlers ausgelöst werden oder auch nicht. Wenn sowohl das Ereignis 'exit' als auch das Ereignis 'error' überwacht werden, sollten Sie sich davor hüten, Handlerfunktionen versehentlich mehrmals aufzurufen.

Siehe auch subprocess.kill() und subprocess.send().

Ereignis: 'exit'

Hinzugefügt in: v0.1.90

  • code <number> Der Exit-Code, falls der Kindprozess von selbst beendet wurde.
  • signal <string> Das Signal, durch das der Kindprozess beendet wurde.

Das Ereignis 'exit' wird ausgelöst, nachdem der Kindprozess beendet wurde. Wenn der Prozess beendet wurde, ist code der endgültige Exit-Code des Prozesses, andernfalls null. Wenn der Prozess aufgrund des Empfangs eines Signals beendet wurde, ist signal der Stringname des Signals, andernfalls null. Einer der beiden Werte ist immer ungleich null.

Wenn das Ereignis 'exit' ausgelöst wird, können die stdio-Streams des Kindprozesses noch geöffnet sein.

Node.js richtet Signalhandler für SIGINT und SIGTERM ein, und Node.js-Prozesse werden aufgrund des Empfangs dieser Signale nicht sofort beendet. Stattdessen führt Node.js eine Reihe von Bereinigungsaktionen durch und löst dann das behandelte Signal erneut aus.

Siehe waitpid(2).

Event: 'message'

Hinzugefügt in: v0.5.9

Das 'message'-Ereignis wird ausgelöst, wenn ein Kindprozess process.send() verwendet, um Nachrichten zu senden.

Die Nachricht durchläuft Serialisierung und Parsen. Die resultierende Nachricht ist möglicherweise nicht die gleiche wie die ursprünglich gesendete.

Wenn die Option serialization beim Erzeugen des Kindprozesses auf 'advanced' gesetzt wurde, kann das message-Argument Daten enthalten, die JSON nicht darstellen kann. Weitere Informationen finden Sie unter Erweiterte Serialisierung.

Event: 'spawn'

Hinzugefügt in: v15.1.0, v14.17.0

Das 'spawn'-Ereignis wird ausgelöst, sobald der Kindprozess erfolgreich erzeugt wurde. Wenn der Kindprozess nicht erfolgreich erzeugt wird, wird das 'spawn'-Ereignis nicht ausgelöst und stattdessen das 'error'-Ereignis ausgelöst.

Wenn es ausgelöst wird, kommt das 'spawn'-Ereignis vor allen anderen Ereignissen und bevor Daten über stdout oder stderr empfangen werden.

Das 'spawn'-Ereignis wird unabhängig davon ausgelöst, ob ein Fehler innerhalb des erzeugten Prozesses auftritt. Wenn beispielsweise bash some-command erfolgreich erzeugt wird, wird das 'spawn'-Ereignis ausgelöst, obwohl bash möglicherweise some-command nicht erzeugen kann. Dieser Vorbehalt gilt auch bei Verwendung von { shell: true }.

subprocess.channel

[Verlauf]

VersionÄnderungen
v14.0.0Das Objekt legt nicht mehr versehentlich native C++-Bindings offen.
v7.1.0Hinzugefügt in: v7.1.0
  • <Object> Eine Pipe, die den IPC-Kanal zum Kindprozess darstellt.

Die subprocess.channel-Eigenschaft ist ein Verweis auf den IPC-Kanal des Kindprozesses. Wenn kein IPC-Kanal vorhanden ist, ist diese Eigenschaft undefined.

subprocess.channel.ref()

Hinzugefügt in: v7.1.0

Diese Methode bewirkt, dass der IPC-Kanal die Ereignisschleife des übergeordneten Prozesses am Laufen hält, falls .unref() zuvor aufgerufen wurde.

subprocess.channel.unref()

Hinzugefügt in: v7.1.0

Diese Methode bewirkt, dass der IPC-Kanal die Ereignisschleife des übergeordneten Prozesses nicht am Laufen hält und sie auch bei geöffnetem Kanal beendet.

subprocess.connected

Hinzugefügt in: v0.7.2

  • <boolean> Wird auf false gesetzt, nachdem subprocess.disconnect() aufgerufen wurde.

Die subprocess.connected-Eigenschaft gibt an, ob es noch möglich ist, Nachrichten von einem Kindprozess zu senden und zu empfangen. Wenn subprocess.connected auf false steht, ist es nicht mehr möglich, Nachrichten zu senden oder zu empfangen.

subprocess.disconnect()

Hinzugefügt in: v0.7.2

Schließt den IPC-Kanal zwischen übergeordneten und untergeordneten Prozessen, sodass der untergeordnete Prozess ordnungsgemäß beendet werden kann, sobald keine anderen Verbindungen mehr bestehen, die ihn am Leben erhalten. Nach dem Aufruf dieser Methode werden die Eigenschaften subprocess.connected und process.connected sowohl im übergeordneten als auch im untergeordneten Prozess (bzw.) auf false gesetzt, und es ist nicht mehr möglich, Nachrichten zwischen den Prozessen auszutauschen.

Das 'disconnect'-Ereignis wird ausgelöst, wenn sich keine Nachrichten im Empfang befinden. Dies wird meistens unmittelbar nach dem Aufruf von subprocess.disconnect() ausgelöst.

Wenn der untergeordnete Prozess eine Node.js-Instanz ist (z. B. erzeugt mit child_process.fork()), kann die Methode process.disconnect() auch innerhalb des untergeordneten Prozesses aufgerufen werden, um den IPC-Kanal zu schließen.

subprocess.exitCode

Die subprocess.exitCode-Eigenschaft gibt den Exit-Code des Kindprozesses an. Wenn der Kindprozess noch läuft, ist das Feld null.

subprocess.kill([signal])

Hinzugefügt in: v0.1.90

Die Methode subprocess.kill() sendet ein Signal an den untergeordneten Prozess. Wenn kein Argument angegeben wird, wird dem Prozess das Signal 'SIGTERM' gesendet. Siehe signal(7) für eine Liste der verfügbaren Signale. Diese Funktion gibt true zurück, wenn kill(2) erfolgreich ist, und false andernfalls.

js
const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);

grep.on('close', (code, signal) => {
  console.log(
    `Kindprozess wurde aufgrund des Empfangs des Signals ${signal} beendet`);
});

// Sende SIGHUP an Prozess.
grep.kill('SIGHUP');
js
import { spawn } from 'node:child_process';
const grep = spawn('grep', ['ssh']);

grep.on('close', (code, signal) => {
  console.log(
    `Kindprozess wurde aufgrund des Empfangs des Signals ${signal} beendet`);
});

// Sende SIGHUP an Prozess.
grep.kill('SIGHUP');

Das ChildProcess-Objekt kann ein 'error'-Ereignis auslösen, wenn das Signal nicht zugestellt werden kann. Das Senden eines Signals an einen untergeordneten Prozess, der bereits beendet wurde, ist kein Fehler, kann aber unvorhergesehene Folgen haben. Insbesondere wenn die Prozesskennung (PID) einem anderen Prozess zugewiesen wurde, wird das Signal stattdessen an diesen Prozess zugestellt, was zu unerwarteten Ergebnissen führen kann.

Obwohl die Funktion kill genannt wird, führt das an den Kindprozess übermittelte Signal nicht unbedingt zur Beendigung des Prozesses.

Siehe kill(2) als Referenz.

Unter Windows, wo keine POSIX-Signale existieren, wird das signal-Argument ignoriert, außer für 'SIGKILL', 'SIGTERM', 'SIGINT' und 'SIGQUIT', und der Prozess wird immer gewaltsam und abrupt beendet (ähnlich wie 'SIGKILL'). Siehe Signal Events für weitere Details.

Unter Linux werden Kindprozesse von Kindprozessen nicht beendet, wenn versucht wird, ihren Elternprozess zu beenden. Dies geschieht wahrscheinlich, wenn ein neuer Prozess in einer Shell oder mit der Option shell von ChildProcess ausgeführt wird:

js
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(); // Beendet nicht den Node.js-Prozess in der Shell.
}, 2000);
js
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(); // Beendet nicht den Node.js-Prozess in der Shell.
}, 2000);

subprocess[Symbol.dispose]()

Hinzugefügt in: v20.5.0, v18.18.0

[Stable: 1 - Experimental]

Stable: 1 Stabilität: 1 - Experimentell

Ruft subprocess.kill() mit 'SIGTERM' auf.

subprocess.killed

Hinzugefügt in: v0.5.10

  • <boolean> Auf true gesetzt, nachdem subprocess.kill() verwendet wurde, um erfolgreich ein Signal an den Kindprozess zu senden.

Die Eigenschaft subprocess.killed gibt an, ob der Kindprozess erfolgreich ein Signal von subprocess.kill() empfangen hat. Die Eigenschaft killed gibt nicht an, dass der Kindprozess beendet wurde.

subprocess.pid

Hinzugefügt in: v0.1.90

Gibt die Prozess-ID (PID) des Kindprozesses zurück. Wenn der Kindprozess aufgrund von Fehlern nicht gestartet werden kann, ist der Wert undefined und error wird ausgelöst.

js
const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);

console.log(`Spawned child pid: ${grep.pid}`);
grep.stdin.end();
js
import { spawn } from 'node:child_process';
const grep = spawn('grep', ['ssh']);

console.log(`Spawned child pid: ${grep.pid}`);
grep.stdin.end();

subprocess.ref()

Hinzugefügt in: v0.7.10

Wenn Sie subprocess.ref() aufrufen, nachdem Sie subprocess.unref() aufgerufen haben, wird die entfernte Referenzanzahl für den Kindprozess wiederhergestellt, wodurch der Elternprozess gezwungen wird, auf das Beenden des Kindprozesses zu warten, bevor er sich selbst beendet.

js
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();
js
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])

[Verlauf]

VersionÄnderungen
v5.8.0Der Parameter options und insbesondere die Option keepOpen werden jetzt unterstützt.
v5.0.0Diese Methode gibt jetzt einen booleschen Wert zur Flusssteuerung zurück.
v4.0.0Der Parameter callback wird jetzt unterstützt.
v0.5.9Hinzugefügt in: v0.5.9
  • message <Object>

  • sendHandle <Handle> | <undefined> undefined oder ein net.Socket-, net.Server- oder dgram.Socket-Objekt.

  • options <Object> Das Argument options ist, falls vorhanden, ein Objekt, das zur Parametrisierung des Sendens bestimmter Handle-Typen verwendet wird. options unterstützt die folgenden Eigenschaften:

    • keepOpen <boolean> Ein Wert, der beim Übergeben von Instanzen von net.Socket verwendet werden kann. Wenn true, wird der Socket im sendenden Prozess offen gehalten. Standard: false.
  • callback <Function>

  • Gibt zurück: <boolean>

Wenn ein IPC-Kanal zwischen dem Eltern- und Kindprozess eingerichtet wurde (d. h. bei Verwendung von child_process.fork()), kann die Methode subprocess.send() verwendet werden, um Nachrichten an den Kindprozess zu senden. Wenn der Kindprozess eine Node.js-Instanz ist, können diese Nachrichten über das 'message'-Ereignis empfangen werden.

Die Nachricht durchläuft Serialisierung und Parsing. Die resultierende Nachricht ist möglicherweise nicht die gleiche wie die ursprünglich gesendete.

Zum Beispiel im Elternskript:

js
const { fork } = require('node:child_process');
const forkedProcess = fork(`${__dirname}/sub.js`);

forkedProcess.on('message', (message) => {
  console.log('PARENT got message:', message);
});

// Veranlasst den Kindprozess, Folgendes auszugeben: CHILD got message: { hello: 'world' }
forkedProcess.send({ hello: 'world' });
js
import { fork } from 'node:child_process';
const forkedProcess = fork(`${import.meta.dirname}/sub.js`);

forkedProcess.on('message', (message) => {
  console.log('PARENT got message:', message);
});

// Veranlasst den Kindprozess, Folgendes auszugeben: CHILD got message: { hello: 'world' }
forkedProcess.send({ hello: 'world' });

Und dann könnte das Kindskript, 'sub.js', wie folgt aussehen:

js
process.on('message', (message) => {
  console.log('CHILD got message:', message);
});

// Veranlasst den Elternprozess, Folgendes auszugeben: PARENT got message: { foo: 'bar', baz: null }
process.send({ foo: 'bar', baz: NaN });

Kind-Node.js-Prozesse haben eine eigene process.send()-Methode, die es dem Kindprozess ermöglicht, Nachrichten zurück an den Elternprozess zu senden.

Es gibt einen Sonderfall beim Senden einer {cmd: 'NODE_foo'}-Nachricht. Nachrichten, die ein NODE_-Präfix in der cmd-Eigenschaft enthalten, sind für die Verwendung innerhalb von Node.js core reserviert und werden nicht im 'message'-Ereignis des Kindes ausgegeben. Stattdessen werden solche Nachrichten mit dem 'internalMessage'-Ereignis ausgegeben und intern von Node.js verarbeitet. Anwendungen sollten es vermeiden, solche Nachrichten zu verwenden oder auf 'internalMessage'-Ereignisse zu hören, da dies ohne Vorankündigung geändert werden kann.

Das optionale sendHandle-Argument, das an subprocess.send() übergeben werden kann, dient zum Übergeben eines TCP-Server- oder Socket-Objekts an den Kindprozess. Der Kindprozess empfängt das Objekt als zweites Argument, das an die Callback-Funktion übergeben wird, die für das 'message'-Ereignis registriert ist. Alle Daten, die im Socket empfangen und gepuffert werden, werden nicht an das Kind gesendet. Das Senden von IPC-Sockets wird unter Windows nicht unterstützt.

Das optionale callback ist eine Funktion, die aufgerufen wird, nachdem die Nachricht gesendet wurde, aber bevor der Kindprozess sie möglicherweise empfangen hat. Die Funktion wird mit einem einzigen Argument aufgerufen: null bei Erfolg oder ein Error-Objekt bei Fehlschlag.

Wenn keine callback-Funktion bereitgestellt wird und die Nachricht nicht gesendet werden kann, wird ein 'error'-Ereignis vom ChildProcess-Objekt ausgegeben. Dies kann beispielsweise vorkommen, wenn der Kindprozess bereits beendet wurde.

subprocess.send() gibt false zurück, wenn der Kanal geschlossen wurde oder wenn der Rückstand nicht gesendeter Nachrichten eine Schwelle überschreitet, die es unklug macht, weitere zu senden. Andernfalls gibt die Methode true zurück. Die callback-Funktion kann verwendet werden, um die Flusssteuerung zu implementieren.

Beispiel: Senden eines Serverobjekts

Das Argument sendHandle kann beispielsweise verwendet werden, um das Handle eines TCP-Serverobjekts an den Kindprozess zu übergeben, wie im folgenden Beispiel veranschaulicht:

js
const { fork } = require('node:child_process');
const { createServer } = require('node:net');

const subprocess = fork('subprocess.js');

// Öffnen Sie das Serverobjekt und senden Sie das Handle.
const server = createServer();
server.on('connection', (socket) => {
  socket.end('handled by parent');
});
server.listen(1337, () => {
  subprocess.send('server', server);
});
js
import { fork } from 'node:child_process';
import { createServer } from 'node:net';

const subprocess = fork('subprocess.js');

// Öffnen Sie das Serverobjekt und senden Sie das Handle.
const server = createServer();
server.on('connection', (socket) => {
  socket.end('handled by parent');
});
server.listen(1337, () => {
  subprocess.send('server', server);
});

Der Kindprozess würde dann das Serverobjekt wie folgt empfangen:

js
process.on('message', (m, server) => {
  if (m === 'server') {
    server.on('connection', (socket) => {
      socket.end('handled by child');
    });
  }
});

Sobald der Server nun zwischen dem Eltern- und dem Kindprozess geteilt ist, können einige Verbindungen vom Elternteil und einige vom Kind verarbeitet werden.

Während das obige Beispiel einen mit dem Modul node:net erstellten Server verwendet, verwenden Server des Moduls node:dgram genau den gleichen Workflow mit den Ausnahmen, dass sie auf ein 'message'-Ereignis anstelle von 'connection' hören und server.bind() anstelle von server.listen() verwenden. Dies wird jedoch nur auf Unix-Plattformen unterstützt.

Beispiel: Senden eines Socket-Objekts

In ähnlicher Weise kann das Argument sendHandler verwendet werden, um das Handle eines Sockets an den Kindprozess zu übergeben. Das folgende Beispiel erzeugt zwei Kinder, die jeweils Verbindungen mit "normaler" oder "spezieller" Priorität verarbeiten:

js
const { fork } = require('node:child_process');
const { createServer } = require('node:net');

const normal = fork('subprocess.js', ['normal']);
const special = fork('subprocess.js', ['special']);

// Öffnen Sie den Server und senden Sie Sockets an das Kind. Verwenden Sie pauseOnConnect, um zu verhindern, dass
// die Sockets gelesen werden, bevor sie an den Kindprozess gesendet werden.
const server = createServer({ pauseOnConnect: true });
server.on('connection', (socket) => {

  // Wenn dies spezielle Priorität hat...
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket);
    return;
  }
  // Dies ist normale Priorität.
  normal.send('socket', socket);
});
server.listen(1337);
js
import { fork } from 'node:child_process';
import { createServer } from 'node:net';

const normal = fork('subprocess.js', ['normal']);
const special = fork('subprocess.js', ['special']);

// Öffnen Sie den Server und senden Sie Sockets an das Kind. Verwenden Sie pauseOnConnect, um zu verhindern, dass
// die Sockets gelesen werden, bevor sie an den Kindprozess gesendet werden.
const server = createServer({ pauseOnConnect: true });
server.on('connection', (socket) => {

  // Wenn dies spezielle Priorität hat...
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket);
    return;
  }
  // Dies ist normale Priorität.
  normal.send('socket', socket);
});
server.listen(1337);

Die subprocess.js würde das Socket-Handle als das zweite an die Ereignis-Callback-Funktion übergebene Argument empfangen:

js
process.on('message', (m, socket) => {
  if (m === 'socket') {
    if (socket) {
      // Überprüfen Sie, ob der Client-Socket vorhanden ist.
      // Es ist möglich, dass der Socket zwischen dem Zeitpunkt, zu dem er gesendet wird, und dem Zeitpunkt, zu dem er im Kindprozess empfangen wird, geschlossen wird.
      socket.end(`Request handled with ${process.argv[2]} priority`);
    }
  }
});

Verwenden Sie kein .maxConnections auf einem Socket, der an einen Unterprozess übergeben wurde. Der Elternprozess kann nicht verfolgen, wann der Socket zerstört wird.

Alle 'message'-Handler im Unterprozess sollten überprüfen, ob socket existiert, da die Verbindung möglicherweise geschlossen wurde, während die Verbindung an das Kind gesendet wurde.

subprocess.signalCode

Die Eigenschaft subprocess.signalCode gibt das vom Kindprozess empfangene Signal an, falls vorhanden, andernfalls null.

subprocess.spawnargs

Die Eigenschaft subprocess.spawnargs stellt die vollständige Liste der Befehlszeilenargumente dar, mit denen der Kindprozess gestartet wurde.

subprocess.spawnfile

Die Eigenschaft subprocess.spawnfile gibt den ausführbaren Dateinamen des gestarteten Kindprozesses an.

Für child_process.fork() entspricht der Wert process.execPath. Für child_process.spawn() ist der Wert der Name der ausführbaren Datei. Für child_process.exec() ist der Wert der Name der Shell, in der der Kindprozess gestartet wird.

subprocess.stderr

Hinzugefügt in: v0.1.90

Ein Readable Stream, der das stderr des Kindprozesses darstellt.

Wenn der Kindprozess mit stdio[2] auf etwas anderes als 'pipe' gesetzt wurde, ist dies null.

subprocess.stderr ist ein Alias für subprocess.stdio[2]. Beide Eigenschaften beziehen sich auf denselben Wert.

Die Eigenschaft subprocess.stderr kann null oder undefined sein, wenn der Kindprozess nicht erfolgreich gestartet werden konnte.

subprocess.stdin

Hinzugefügt in: v0.1.90

Ein Writable Stream, der die stdin des Kindprozesses darstellt.

Wenn ein Kindprozess darauf wartet, seine gesamte Eingabe zu lesen, wird der Kindprozess erst fortgesetzt, wenn dieser Stream über end() geschlossen wurde.

Wenn der Kindprozess mit stdio[0] auf einen anderen Wert als 'pipe' gestartet wurde, ist dieser Wert null.

subprocess.stdin ist ein Alias für subprocess.stdio[0]. Beide Eigenschaften verweisen auf denselben Wert.

Die Eigenschaft subprocess.stdin kann null oder undefined sein, wenn der Kindprozess nicht erfolgreich gestartet werden konnte.

subprocess.stdio

Hinzugefügt in: v0.7.10

Ein spärliches Array von Pipes zum Kindprozess, das Positionen in der stdio-Option entspricht, die an child_process.spawn() übergeben wurde und auf den Wert 'pipe' gesetzt wurde. subprocess.stdio[0], subprocess.stdio[1] und subprocess.stdio[2] sind auch als subprocess.stdin, subprocess.stdout bzw. subprocess.stderr verfügbar.

Im folgenden Beispiel ist nur die fd 1 (stdout) des Kindprozesses als Pipe konfiguriert, sodass nur die subprocess.stdio[1] des Elternprozesses ein Stream ist, alle anderen Werte im Array sind null.

js
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, // Use parent's stdin for child.
    'pipe', // Pipe child's stdout to parent.
    fs.openSync('err.out', 'w'), // Direct child's stderr to a file.
  ],
});

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);
js
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, // Use parent's stdin for child.
    'pipe', // Pipe child's stdout to parent.
    fs.openSync('err.out', 'w'), // Direct child's stderr to a file.
  ],
});

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);

Die Eigenschaft subprocess.stdio kann undefined sein, wenn der Kindprozess nicht erfolgreich gestartet werden konnte.

subprocess.stdout

Hinzugefügt in: v0.1.90

Ein Readable Stream, der das stdout des Kindprozesses darstellt.

Wenn der Kindprozess mit stdio[1] auf etwas anderes als 'pipe' gesetzt wurde, dann ist dies null.

subprocess.stdout ist ein Alias für subprocess.stdio[1]. Beide Eigenschaften beziehen sich auf denselben Wert.

js
const { spawn } = require('node:child_process');

const subprocess = spawn('ls');

subprocess.stdout.on('data', (data) => {
  console.log(`Received chunk ${data}`);
});
js
import { spawn } from 'node:child_process';

const subprocess = spawn('ls');

subprocess.stdout.on('data', (data) => {
  console.log(`Received chunk ${data}`);
});

Die Eigenschaft subprocess.stdout kann null oder undefined sein, wenn der Kindprozess nicht erfolgreich gestartet werden konnte.

subprocess.unref()

Hinzugefügt in: v0.7.10

Standardmäßig wartet der Elternprozess darauf, dass sich der getrennte Kindprozess beendet. Um zu verhindern, dass der Elternprozess auf die Beendigung eines bestimmten subprocess wartet, verwenden Sie die Methode subprocess.unref(). Dadurch wird die Ereignisschleife des Elternprozesses den Kindprozess nicht in ihre Referenzzählung aufnehmen, sodass sich der Elternprozess unabhängig vom Kind beenden kann, es sei denn, es besteht ein etablierter IPC-Kanal zwischen dem Kind- und dem Elternprozess.

js
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();
js
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 und Unicode

Die Option maxBuffer gibt die maximale Anzahl von Bytes an, die auf stdout oder stderr zulässig sind. Wenn dieser Wert überschritten wird, wird der Kindprozess beendet. Dies wirkt sich auf die Ausgabe aus, die Multibyte-Zeichencodierungen wie UTF-8 oder UTF-16 enthält. Zum Beispiel sendet console.log('中文测试') 13 UTF-8-kodierte Bytes an stdout, obwohl es nur 4 Zeichen sind.

Shell-Anforderungen

Die Shell sollte den Schalter -c verstehen. Wenn die Shell 'cmd.exe' ist, sollte sie die Schalter /d /s /c verstehen und die Befehlszeilenanalyse sollte kompatibel sein.

Standard-Windows-Shell

Obwohl Microsoft festlegt, dass %COMSPEC% den Pfad zu 'cmd.exe' in der Stammumgebung enthalten muss, unterliegen Kindprozesse nicht immer derselben Anforderung. Daher wird in child_process-Funktionen, in denen eine Shell gestartet werden kann, 'cmd.exe' als Fallback verwendet, wenn process.env.ComSpec nicht verfügbar ist.

Erweiterte Serialisierung

Hinzugefügt in: v13.2.0, v12.16.0

Kindprozesse unterstützen einen Serialisierungsmechanismus für IPC, der auf der Serialisierungs-API des node:v8-Moduls basiert, die auf dem HTML structured clone algorithm basiert. Dies ist im Allgemeinen leistungsfähiger und unterstützt mehr integrierte JavaScript-Objekttypen, wie z. B. BigInt, Map und Set, ArrayBuffer und TypedArray, Buffer, Error, RegExp usw.

Dieses Format ist jedoch keine vollständige Obermenge von JSON, und z. B. Eigenschaften, die auf Objekten solcher integrierten Typen gesetzt sind, werden nicht durch den Serialisierungsschritt weitergegeben. Darüber hinaus ist die Leistung möglicherweise nicht äquivalent zu der von JSON, abhängig von der Struktur der übergebenen Daten. Daher erfordert diese Funktion die Aktivierung, indem die Option serialization auf 'advanced' gesetzt wird, wenn child_process.spawn() oder child_process.fork() aufgerufen wird.