Processo figlio
[Stabile: 2 - Stabile]
Stabile: 2 Stabilità: 2 - Stabile
Codice sorgente: lib/child_process.js
Il modulo node:child_process
fornisce la capacità di generare sottoprocessi in un modo simile, ma non identico, a popen(3)
. Questa capacità è fornita principalmente dalla funzione child_process.spawn()
:
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}`);
});
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}`);
});
Per impostazione predefinita, i pipe per stdin
, stdout
e stderr
sono stabiliti tra il processo Node.js padre e il sottoprocesso generato. Questi pipe hanno una capacità limitata (e specifica per la piattaforma). Se il sottoprocesso scrive su stdout superando tale limite senza che l'output venga catturato, il sottoprocesso si blocca in attesa che il buffer del pipe accetti più dati. Questo è identico al comportamento dei pipe nella shell. Utilizzare l'opzione { stdio: 'ignore' }
se l'output non verrà utilizzato.
La ricerca del comando viene eseguita utilizzando la variabile d'ambiente options.env.PATH
se env
si trova nell'oggetto options
. Altrimenti, viene utilizzato process.env.PATH
. Se options.env
è impostato senza PATH
, la ricerca su Unix viene eseguita su un percorso di ricerca predefinito di /usr/bin:/bin
(consultare il manuale del sistema operativo per execvpe/execvp), su Windows viene utilizzata la variabile d'ambiente PATH
del processo corrente.
Su Windows, le variabili d'ambiente non fanno distinzione tra maiuscole e minuscole. Node.js ordina lessicograficamente le chiavi env
e utilizza la prima che corrisponde senza distinzione tra maiuscole e minuscole. Solo la prima voce (in ordine lessicografico) verrà passata al sottoprocesso. Ciò potrebbe causare problemi su Windows quando si passano oggetti all'opzione env
che hanno più varianti della stessa chiave, come PATH
e Path
.
Il metodo child_process.spawn()
genera il processo figlio in modo asincrono, senza bloccare il ciclo di eventi di Node.js. La funzione child_process.spawnSync()
fornisce funzionalità equivalenti in modo sincrono che blocca il ciclo di eventi fino a quando il processo generato non termina o viene terminato.
Per comodità, il modulo node:child_process
fornisce una manciata di alternative sincrone e asincrone a child_process.spawn()
e child_process.spawnSync()
. Ciascuna di queste alternative è implementata sopra a child_process.spawn()
o child_process.spawnSync()
.
child_process.exec()
: genera una shell ed esegue un comando all'interno di tale shell, passandostdout
estderr
a una funzione di callback al termine.child_process.execFile()
: simile achild_process.exec()
tranne per il fatto che genera il comando direttamente senza prima generare una shell per impostazione predefinita.child_process.fork()
: genera un nuovo processo Node.js e richiama un modulo specificato con un canale di comunicazione IPC stabilito che consente l'invio di messaggi tra padre e figlio.child_process.execSync()
: una versione sincrona dichild_process.exec()
che bloccherà il ciclo di eventi di Node.js.child_process.execFileSync()
: una versione sincrona dichild_process.execFile()
che bloccherà il ciclo di eventi di Node.js.
Per alcuni casi d'uso, come l'automazione di script di shell, le controparti sincronizzate possono essere più convenienti. In molti casi, tuttavia, i metodi sincroni possono avere un impatto significativo sulle prestazioni a causa del blocco del ciclo di eventi mentre i processi generati vengono completati.
Creazione asincrona di processi
I metodi child_process.spawn()
, child_process.fork()
, child_process.exec()
e child_process.execFile()
seguono tutti l'idiomatico pattern di programmazione asincrona tipico delle altre API di Node.js.
Ciascuno dei metodi restituisce un'istanza di ChildProcess
. Questi oggetti implementano l'API EventEmitter
di Node.js, consentendo al processo padre di registrare funzioni di listener che vengono chiamate quando si verificano determinati eventi durante il ciclo di vita del processo figlio.
I metodi child_process.exec()
e child_process.execFile()
consentono inoltre di specificare una funzione callback
opzionale che viene richiamata quando il processo figlio termina.
Generazione di file .bat
e .cmd
su Windows
L'importanza della distinzione tra child_process.exec()
e child_process.execFile()
può variare in base alla piattaforma. Sui sistemi operativi di tipo Unix (Unix, Linux, macOS) child_process.execFile()
può essere più efficiente perché non genera una shell per impostazione predefinita. Su Windows, tuttavia, i file .bat
e .cmd
non sono eseguibili da soli senza un terminale e pertanto non possono essere avviati utilizzando child_process.execFile()
. Quando si esegue su Windows, i file .bat
e .cmd
possono essere richiamati utilizzando child_process.spawn()
con l'opzione shell
impostata, con child_process.exec()
, o generando cmd.exe
e passando il file .bat
o .cmd
come argomento (che è ciò che fanno l'opzione shell
e child_process.exec()
). In ogni caso, se il nome del file dello script contiene spazi, deve essere racchiuso tra virgolette.
// OR...
const { exec, spawn } = require('node:child_process');
exec('my.bat', (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(stdout);
});
// Script con spazi nel nome del file:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
// or:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
// ...
});
// OR...
import { exec, spawn } from 'node:child_process';
exec('my.bat', (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(stdout);
});
// Script con spazi nel nome del file:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
// or:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
// ...
});
child_process.exec(command[, options][, callback])
[Cronologia]
Versione | Modifiche |
---|---|
v15.4.0 | È stato aggiunto il supporto per AbortSignal. |
v16.4.0, v14.18.0 | L'opzione cwd può essere un oggetto URL WHATWG che utilizza il protocollo file: . |
v8.8.0 | L'opzione windowsHide è ora supportata. |
v0.1.90 | Aggiunto in: v0.1.90 |
command
<stringa> Il comando da eseguire, con argomenti separati da spazi.options
<Object>cwd
<stringa> | <URL> Directory di lavoro corrente del processo figlio. Predefinito:process.cwd()
.env
<Object> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.encoding
<stringa> Predefinito:'utf8'
shell
<stringa> Shell con cui eseguire il comando. Vedi Requisiti della shell e Shell predefinita di Windows. Predefinito:'/bin/sh'
su Unix,process.env.ComSpec
su Windows.signal
<AbortSignal> consente di interrompere il processo figlio utilizzando un AbortSignal.timeout
<numero> Predefinito:0
maxBuffer
<numero> La massima quantità di dati in byte consentita su stdout o stderr. Se superata, il processo figlio viene terminato e qualsiasi output viene troncato. Vedi l'avvertenza sumaxBuffer
e Unicode. Predefinito:1024 * 1024
.killSignal
<stringa> | <numero intero> Predefinito:'SIGTERM'
uid
<numero> Imposta l'identità utente del processo (vedisetuid(2)
).gid
<numero> Imposta l'identità del gruppo del processo (vedisetgid(2)
).windowsHide
<booleano> Nasconde la finestra della console del sottoprocesso che normalmente verrebbe creata sui sistemi Windows. Predefinito:false
.
callback
<Funzione> chiamata con l'output quando il processo termina.Restituisce: <ChildProcess>
Genera una shell quindi esegue il command
all'interno di quella shell, memorizzando nel buffer qualsiasi output generato. La stringa command
passata alla funzione exec viene elaborata direttamente dalla shell e i caratteri speciali (variano in base alla shell) devono essere gestiti di conseguenza:
const { exec } = require('node:child_process');
exec('"/path/to/test file/test.sh" arg1 arg2');
// Le virgolette doppie vengono utilizzate in modo che lo spazio nel percorso non venga interpretato come
// un delimitatore di argomenti multipli.
exec('echo "La variabile \\$HOME è $HOME"');
// La variabile $HOME è preceduta da escape nella prima istanza, ma non nella seconda.
import { exec } from 'node:child_process';
exec('"/path/to/test file/test.sh" arg1 arg2');
// Le virgolette doppie vengono utilizzate in modo che lo spazio nel percorso non venga interpretato come
// un delimitatore di argomenti multipli.
exec('echo "La variabile \\$HOME è $HOME"');
// La variabile $HOME è preceduta da escape nella prima istanza, ma non nella seconda.
Non passare mai input utente non sanificati a questa funzione. Qualsiasi input contenente metacaratteri shell può essere utilizzato per attivare l'esecuzione di comandi arbitrari.
Se viene fornita una funzione callback
, viene chiamata con gli argomenti (error, stdout, stderr)
. In caso di successo, error
sarà null
. In caso di errore, error
sarà un'istanza di Error
. La proprietà error.code
sarà il codice di uscita del processo. Per convenzione, qualsiasi codice di uscita diverso da 0
indica un errore. error.signal
sarà il segnale che ha terminato il processo.
Gli argomenti stdout
e stderr
passati al callback conterranno l'output stdout e stderr del processo figlio. Per impostazione predefinita, Node.js decodificherà l'output come UTF-8 e passerà stringhe al callback. L'opzione encoding
può essere utilizzata per specificare la codifica dei caratteri utilizzata per decodificare l'output stdout e stderr. Se encoding
è 'buffer'
, o una codifica dei caratteri non riconosciuta, gli oggetti Buffer
verranno passati al callback.
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}`);
});
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}`);
});
Se timeout
è maggiore di 0
, il processo padre invierà il segnale identificato dalla proprietà killSignal
(il valore predefinito è 'SIGTERM'
) se il processo figlio viene eseguito più a lungo di timeout
millisecondi.
A differenza della chiamata di sistema POSIX exec(3)
, child_process.exec()
non sostituisce il processo esistente e utilizza una shell per eseguire il comando.
Se questo metodo viene richiamato come versione util.promisify()
ed, restituisce una Promise
per un Object
con proprietà stdout
e stderr
. L'istanza ChildProcess
restituita è collegata alla Promise
come proprietà child
. In caso di errore (incluso qualsiasi errore che comporti un codice di uscita diverso da 0), viene restituita una promise rifiutata, con lo stesso oggetto error
fornito nel callback, ma con due proprietà aggiuntive stdout
e stderr
.
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();
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();
Se l'opzione signal
è abilitata, chiamare .abort()
sul corrispondente AbortController
è simile a chiamare .kill()
sul processo figlio, tranne per il fatto che l'errore passato al callback sarà un AbortError
:
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();
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])
[Cronologia]
Versione | Modifiche |
---|---|
v16.4.0, v14.18.0 | L'opzione cwd può essere un oggetto URL WHATWG che utilizza il protocollo file: . |
v15.4.0, v14.17.0 | È stato aggiunto il supporto per AbortSignal. |
v8.8.0 | L'opzione windowsHide è ora supportata. |
v0.1.91 | Aggiunto in: v0.1.91 |
file
<stringa> Il nome o il percorso del file eseguibile da eseguire.args
<stringa[]> Elenco di argomenti stringa.options
<Oggetto>cwd
<stringa> | <URL> Directory di lavoro corrente del processo figlio.env
<Oggetto> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.encoding
<stringa> Predefinito:'utf8'
timeout
<numero> Predefinito:0
maxBuffer
<numero> La quantità massima di dati in byte consentita su stdout o stderr. Se superata, il processo figlio viene terminato e qualsiasi output viene troncato. Vedi l'avvertenza inmaxBuffer
e Unicode. Predefinito:1024 * 1024
.killSignal
<stringa> | <numero intero> Predefinito:'SIGTERM'
uid
<numero> Imposta l'identità utente del processo (vedisetuid(2)
).gid
<numero> Imposta l'identità del gruppo del processo (vedisetgid(2)
).windowsHide
<booleano> Nascondi la finestra della console del sottoprocesso che normalmente verrebbe creata sui sistemi Windows. Predefinito:false
.windowsVerbatimArguments
<booleano> Nessuna citazione o escape degli argomenti viene eseguita su Windows. Ignorato su Unix. Predefinito:false
.shell
<booleano> | <stringa> Setrue
, eseguecommand
all'interno di una shell. Utilizza'/bin/sh'
su Unix eprocess.env.ComSpec
su Windows. Una shell diversa può essere specificata come stringa. Vedi Requisiti della shell e Shell predefinita di Windows. Predefinito:false
(nessuna shell).signal
<AbortSignal> consente di interrompere il processo figlio utilizzando un AbortSignal.
callback
<Funzione> Chiamata con l'output quando il processo termina.Restituisce: <ChildProcess>
La funzione child_process.execFile()
è simile a child_process.exec()
tranne per il fatto che non genera una shell per impostazione predefinita. Piuttosto, il file
eseguibile specificato viene generato direttamente come un nuovo processo, rendendolo leggermente più efficiente di child_process.exec()
.
Sono supportate le stesse opzioni di child_process.exec()
. Poiché una shell non viene generata, comportamenti come il reindirizzamento I/O e il file globbing non sono supportati.
const { execFile } = require('node:child_process');
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
import { execFile } from 'node:child_process';
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
Gli argomenti stdout
e stderr
passati alla callback conterranno l'output stdout e stderr del processo figlio. Per impostazione predefinita, Node.js decodificherà l'output come UTF-8 e passerà le stringhe alla callback. L'opzione encoding
può essere utilizzata per specificare la codifica dei caratteri utilizzata per decodificare l'output stdout e stderr. Se encoding
è 'buffer'
, o una codifica dei caratteri non riconosciuta, gli oggetti Buffer
verranno invece passati alla callback.
Se questo metodo viene richiamato come versione util.promisify()
ed, restituisce una Promise
per un Oggetto
con proprietà stdout
e stderr
. L'istanza ChildProcess
restituita è collegata alla Promise
come proprietà child
. In caso di errore (incluso qualsiasi errore che comporti un codice di uscita diverso da 0), viene restituita una promise rifiutata, con lo stesso oggetto error
fornito nella callback, ma con due proprietà aggiuntive stdout
e stderr
.
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();
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();
Se l'opzione shell
è abilitata, non passare input utente non sanitizzato a questa funzione. Qualsiasi input contenente metacaratteri della shell può essere utilizzato per attivare l'esecuzione di comandi arbitrari.
Se l'opzione signal
è abilitata, chiamare .abort()
sul corrispondente AbortController
è simile a chiamare .kill()
sul processo figlio, tranne per il fatto che l'errore passato alla callback sarà un AbortError
:
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();
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])
[Cronologia]
Versione | Modifiche |
---|---|
v17.4.0, v16.14.0 | Il parametro modulePath può essere un oggetto URL WHATWG che utilizza il protocollo file: . |
v16.4.0, v14.18.0 | L'opzione cwd può essere un oggetto URL WHATWG che utilizza il protocollo file: . |
v15.13.0, v14.18.0 | È stato aggiunto il timeout. |
v15.11.0, v14.18.0 | È stato aggiunto killSignal per AbortSignal. |
v15.6.0, v14.17.0 | È stato aggiunto il supporto per AbortSignal. |
v13.2.0, v12.16.0 | L'opzione serialization è ora supportata. |
v8.0.0 | L'opzione stdio ora può essere una stringa. |
v6.4.0 | L'opzione stdio è ora supportata. |
v0.5.0 | Aggiunto in: v0.5.0 |
modulePath
<stringa> | <URL> Il modulo da eseguire nel child.args
<stringa[]> Elenco di argomenti stringa.options
<Oggetto>cwd
<stringa> | <URL> Directory di lavoro corrente del processo child.detached
<booleano> Prepara il processo child per l'esecuzione indipendente dal suo processo padre. Il comportamento specifico dipende dalla piattaforma, vedioptions.detached
).env
<Oggetto> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.execPath
<stringa> Eseguibile utilizzato per creare il processo child.execArgv
<stringa[]> Elenco di argomenti stringa passati all'eseguibile. Predefinito:process.execArgv
.gid
<numero> Imposta l'identità del gruppo del processo (vedisetgid(2)
).serialization
<stringa> Specifica il tipo di serializzazione utilizzato per l'invio di messaggi tra i processi. I valori possibili sono'json'
e'advanced'
. Vedi Serializzazione avanzata per maggiori dettagli. Predefinito:'json'
.signal
<AbortSignal> Consente la chiusura del processo child utilizzando un AbortSignal.killSignal
<stringa> | <numero intero> Il valore del segnale da utilizzare quando il processo generato verrà interrotto dal timeout o dal segnale di interruzione. Predefinito:'SIGTERM'
.silent
<booleano> Setrue
, stdin, stdout e stderr del processo child verranno reindirizzati al processo padre, altrimenti verranno ereditati dal processo padre, vedi le opzioni'pipe'
e'inherit'
per lostdio
dichild_process.spawn()
per maggiori dettagli. Predefinito:false
.stdio
<Array> | <stringa> Vedi lostdio
dichild_process.spawn()
. Quando questa opzione viene fornita, sovrascrivesilent
. Se viene utilizzata la variante array, deve contenere esattamente un elemento con valore'ipc'
o verrà generato un errore. Ad esempio[0, 1, 2, 'ipc']
.uid
<numero> Imposta l'identità dell'utente del processo (vedisetuid(2)
).windowsVerbatimArguments
<booleano> Nessuna citazione o escape degli argomenti viene eseguita su Windows. Ignorato su Unix. Predefinito:false
.timeout
<numero> In millisecondi, la quantità massima di tempo in cui il processo può essere eseguito. Predefinito:undefined
.
Restituisce: <ChildProcess>
Il metodo child_process.fork()
è un caso speciale di child_process.spawn()
utilizzato specificamente per generare nuovi processi Node.js. Come child_process.spawn()
, viene restituito un oggetto ChildProcess
. Il ChildProcess
restituito avrà un canale di comunicazione aggiuntivo integrato che consente di passare messaggi avanti e indietro tra il padre e il child. Vedi subprocess.send()
per i dettagli.
Tieni presente che i processi child Node.js generati sono indipendenti dal padre, ad eccezione del canale di comunicazione IPC stabilito tra i due. Ogni processo ha la propria memoria, con le proprie istanze V8. A causa delle allocazioni di risorse aggiuntive richieste, non è consigliabile generare un numero elevato di processi child Node.js.
Per impostazione predefinita, child_process.fork()
genererà nuove istanze Node.js utilizzando il process.execPath
del processo padre. La proprietà execPath
nell'oggetto options
consente di utilizzare un percorso di esecuzione alternativo.
I processi Node.js avviati con un execPath
personalizzato comunicheranno con il processo padre utilizzando il descrittore di file (fd) identificato tramite la variabile di ambiente NODE_CHANNEL_FD
nel processo child.
A differenza della chiamata di sistema POSIX fork(2)
, child_process.fork()
non clona il processo corrente.
L'opzione shell
disponibile in child_process.spawn()
non è supportata da child_process.fork()
e verrà ignorata se impostata.
Se l'opzione signal
è abilitata, chiamare .abort()
sul corrispondente AbortController
è simile a chiamare .kill()
sul processo child, tranne per il fatto che l'errore passato al callback sarà un AbortError
:
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
}
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])
[Cronologia]
Versione | Modifiche |
---|---|
v16.4.0, v14.18.0 | L'opzione cwd può essere un oggetto URL WHATWG utilizzando il protocollo file: . |
v15.13.0, v14.18.0 | È stato aggiunto timeout. |
v15.11.0, v14.18.0 | È stato aggiunto killSignal per AbortSignal. |
v15.5.0, v14.17.0 | È stato aggiunto il supporto per AbortSignal. |
v13.2.0, v12.16.0 | L'opzione serialization è ora supportata. |
v8.8.0 | L'opzione windowsHide è ora supportata. |
v6.4.0 | L'opzione argv0 è ora supportata. |
v5.7.0 | L'opzione shell è ora supportata. |
v0.1.90 | Aggiunto in: v0.1.90 |
command
<stringa> Il comando da eseguire.args
<stringa[]> Elenco degli argomenti stringa.options
<Oggetto>cwd
<stringa> | <URL> Directory di lavoro corrente del processo figlio.env
<Oggetto> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.argv0
<stringa> Imposta esplicitamente il valore diargv[0]
inviato al processo figlio. Questo verrà impostato sucommand
se non specificato.stdio
<Array> | <stringa> Configurazione stdio del figlio (vedereoptions.stdio
).detached
<boolean> Prepara il processo figlio per l'esecuzione indipendentemente dal suo processo padre. Il comportamento specifico dipende dalla piattaforma, vedereoptions.detached
).uid
<numero> Imposta l'identità utente del processo (vederesetuid(2)
).gid
<numero> Imposta l'identità del gruppo del processo (vederesetgid(2)
).serialization
<stringa> Specifica il tipo di serializzazione utilizzato per l'invio di messaggi tra i processi. I valori possibili sono'json'
e'advanced'
. Vedi Serializzazione avanzata per maggiori dettagli. Predefinito:'json'
.shell
<boolean> | <stringa> Setrue
, eseguecommand
all'interno di una shell. Utilizza'/bin/sh'
su Unix eprocess.env.ComSpec
su Windows. Una shell diversa può essere specificata come una stringa. Vedi Requisiti della shell e Shell Windows predefinita. Predefinito:false
(nessuna shell).windowsVerbatimArguments
<boolean> Nessuna citazione o escape degli argomenti viene eseguita su Windows. Ignorato su Unix. Questo è impostato sutrue
automaticamente quandoshell
è specificato ed è CMD. Predefinito:false
.windowsHide
<boolean> Nascondi la finestra della console del sottoprocesso che normalmente verrebbe creata sui sistemi Windows. Predefinito:false
.signal
<AbortSignal> consente di interrompere il processo figlio utilizzando un AbortSignal.timeout
<numero> In millisecondi la quantità massima di tempo in cui il processo può essere eseguito. Predefinito:undefined
.killSignal
<stringa> | <intero> Il valore del segnale da utilizzare quando il processo generato verrà interrotto per timeout o segnale di interruzione. Predefinito:'SIGTERM'
.
Restituisce: <ChildProcess>
Il metodo child_process.spawn()
genera un nuovo processo utilizzando il comando
fornito, con argomenti della riga di comando in args
. Se omesso, args
predefinisce un array vuoto.
Se l'opzione shell
è abilitata, non passare input utente non sanitizzato a questa funzione. Qualsiasi input contenente metacaratteri shell può essere utilizzato per attivare l'esecuzione arbitraria di comandi.
Un terzo argomento può essere utilizzato per specificare opzioni aggiuntive, con queste impostazioni predefinite:
const defaults = {
cwd: undefined,
env: process.env,
};
Utilizzare cwd
per specificare la directory di lavoro da cui viene generato il processo. Se non specificato, l'impostazione predefinita è ereditare la directory di lavoro corrente. Se specificato, ma il percorso non esiste, il processo figlio emette un errore ENOENT
e si chiude immediatamente. ENOENT
viene emesso anche quando il comando non esiste.
Utilizzare env
per specificare le variabili di ambiente che saranno visibili al nuovo processo, l'impostazione predefinita è process.env
.
I valori undefined
in env
verranno ignorati.
Esempio di esecuzione di ls -lh /usr
, acquisendo stdout
, stderr
e il codice di uscita:
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}`);
});
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}`);
});
Esempio: Un modo molto elaborato per eseguire ps ax | grep ssh
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}`);
}
});
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}`);
}
});
Esempio di verifica della presenza di spawn
non riuscito:
const { spawn } = require('node:child_process');
const subprocess = spawn('bad_command');
subprocess.on('error', (err) => {
console.error('Failed to start subprocess.');
});
import { spawn } from 'node:child_process';
const subprocess = spawn('bad_command');
subprocess.on('error', (err) => {
console.error('Failed to start subprocess.');
});
Alcune piattaforme (macOS, Linux) useranno il valore di argv[0]
per il titolo del processo, mentre altre (Windows, SunOS) useranno command
.
Node.js sovrascrive argv[0]
con process.execPath
all'avvio, quindi process.argv[0]
in un processo figlio Node.js non corrisponderà al parametro argv0
passato a spawn
dal padre. Recuperalo invece con la proprietà process.argv0
.
Se l'opzione signal
è abilitata, chiamare .abort()
sul AbortController
corrispondente è simile a chiamare .kill()
sul processo figlio, tranne per il fatto che l'errore passato al callback sarà un AbortError
:
const { spawn } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const grep = spawn('grep', ['ssh'], { signal });
grep.on('error', (err) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process
import { spawn } from 'node:child_process';
const controller = new AbortController();
const { signal } = controller;
const grep = spawn('grep', ['ssh'], { signal });
grep.on('error', (err) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process
options.detached
Aggiunto in: v0.7.10
Su Windows, impostare options.detached
a true
consente al processo figlio di continuare a essere eseguito dopo che il processo padre termina. Il processo figlio avrà la sua finestra della console. Una volta abilitato per un processo figlio, non può essere disabilitato.
Su piattaforme non Windows, se options.detached
è impostato su true
, il processo figlio diventerà il leader di un nuovo gruppo di processi e sessione. I processi figli possono continuare a essere eseguiti dopo che il processo padre termina, indipendentemente dal fatto che siano detached o meno. Vedere setsid(2)
per maggiori informazioni.
Per impostazione predefinita, il processo padre aspetterà che il processo figlio detached termini. Per impedire al processo padre di aspettare che un determinato subprocess
termini, usare il metodo subprocess.unref()
. In questo modo, il ciclo di eventi del processo padre non includerà il processo figlio nel suo conteggio dei riferimenti, consentendo al processo padre di terminare indipendentemente dal processo figlio, a meno che non esista un canale IPC stabilito tra il processo figlio e il processo padre.
Quando si utilizza l'opzione detached
per avviare un processo di lunga durata, il processo non rimarrà in esecuzione in background dopo che il processo padre termina, a meno che non venga fornita una configurazione stdio
che non sia connessa al processo padre. Se lo stdio
del processo padre viene ereditato, il processo figlio rimarrà collegato al terminale di controllo.
Esempio di un processo di lunga durata, tramite detached e ignorando anche i descrittori di file stdio
del processo padre, al fine di ignorare la terminazione del processo padre:
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();
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();
In alternativa, si può reindirizzare l'output del processo figlio in file:
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();
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
[Cronologia]
Versione | Modifiche |
---|---|
v15.6.0, v14.18.0 | Aggiunta la flag stdio overlapped . |
v3.3.1 | Il valore 0 è ora accettato come descrittore di file. |
v0.7.10 | Aggiunto in: v0.7.10 |
L'opzione options.stdio
viene utilizzata per configurare i pipe che vengono stabiliti tra il processo padre e il processo figlio. Per impostazione predefinita, stdin, stdout e stderr del figlio vengono reindirizzati ai corrispondenti stream subprocess.stdin
, subprocess.stdout
e subprocess.stderr
sull'oggetto ChildProcess
. Ciò equivale a impostare options.stdio
uguale a ['pipe', 'pipe', 'pipe']
.
Per comodità, options.stdio
può essere una delle seguenti stringhe:
'pipe'
: equivalente a['pipe', 'pipe', 'pipe']
(il valore predefinito)'overlapped'
: equivalente a['overlapped', 'overlapped', 'overlapped']
'ignore'
: equivalente a['ignore', 'ignore', 'ignore']
'inherit'
: equivalente a['inherit', 'inherit', 'inherit']
oppure[0, 1, 2]
Altrimenti, il valore di options.stdio
è un array in cui ogni indice corrisponde a un fd nel figlio. Gli fd 0, 1 e 2 corrispondono rispettivamente a stdin, stdout e stderr. È possibile specificare fd aggiuntivi per creare pipe aggiuntive tra il padre e il figlio. Il valore è uno dei seguenti:
const { spawn } = require('node:child_process');
const process = require('node:process');
// Il figlio utilizzerà gli stdio del padre.
spawn('prg', [], { stdio: 'inherit' });
// Genera il figlio condividendo solo stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });
// Apri un fd=4 extra, per interagire con programmi che presentano un'interfaccia
// in stile startd.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });
import { spawn } from 'node:child_process';
import process from 'node:process';
// Il figlio utilizzerà gli stdio del padre.
spawn('prg', [], { stdio: 'inherit' });
// Genera il figlio condividendo solo stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });
// Apri un fd=4 extra, per interagire con programmi che presentano un'interfaccia
// in stile startd.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });
Vale la pena notare che quando viene stabilito un canale IPC tra i processi padre e figlio e il processo figlio è un'istanza di Node.js, il processo figlio viene avviato con il canale IPC non referenziato (utilizzando unref()
) finché il processo figlio non registra un gestore di eventi per l'evento 'disconnect'
o l'evento 'message'
. Ciò consente al processo figlio di terminare normalmente senza che il processo venga mantenuto aperto dal canale IPC aperto. Vedi anche: child_process.exec()
e child_process.fork()
.
Creazione sincrona del processo
I metodi child_process.spawnSync()
, child_process.execSync()
e child_process.execFileSync()
sono sincroni e bloccheranno il ciclo di eventi di Node.js, sospendendo l'esecuzione di qualsiasi codice aggiuntivo fino a quando il processo generato non si chiude.
Le chiamate bloccanti come queste sono per lo più utili per semplificare le attività di scripting generiche e per semplificare il caricamento/elaborazione della configurazione dell'applicazione all'avvio.
child_process.execFileSync(file[, args][, options])
[Cronologia]
Versione | Modifiche |
---|---|
v16.4.0, v14.18.0 | L'opzione cwd può essere un oggetto URL WHATWG utilizzando il protocollo file: . |
v10.10.0 | L'opzione input ora può essere qualsiasi TypedArray o DataView . |
v8.8.0 | L'opzione windowsHide è ora supportata. |
v8.0.0 | L'opzione input ora può essere un Uint8Array . |
v6.2.1, v4.5.0 | L'opzione encoding ora può essere impostata esplicitamente su buffer . |
v0.11.12 | Aggiunto in: v0.11.12 |
file
<stringa> Il nome o il percorso del file eseguibile da eseguire.args
<stringa[]> Elenco di argomenti stringa.options
<Oggetto>cwd
<stringa> | <URL> Directory di lavoro corrente del processo figlio.input
<stringa> | <Buffer> | <TypedArray> | <DataView> Il valore che verrà passato come stdin al processo generato. Sestdio[0]
è impostato su'pipe'
, fornire questo valore sovrascriveràstdio[0]
.stdio
<stringa> | <Array> Configurazione stdio del figlio. Vedichild_process.spawn()
'sstdio
.stderr
per impostazione predefinita verrà inviato all'stderr del processo padre a meno che non sia specificatostdio
. Predefinito:'pipe'
.env
<Oggetto> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.uid
<numero> Imposta l'identità utente del processo (vedisetuid(2)
).gid
<numero> Imposta l'identità del gruppo del processo (vedisetgid(2)
).timeout
<numero> In millisecondi la quantità massima di tempo in cui è consentito l'esecuzione del processo. Predefinito:undefined
.killSignal
<stringa> | <numero intero> Il valore del segnale da utilizzare quando il processo generato verrà terminato. Predefinito:'SIGTERM'
.maxBuffer
<numero> La quantità massima di dati in byte consentita su stdout o stderr. Se superata, il processo figlio viene terminato. Vedi avvertenza inmaxBuffer
e Unicode. Predefinito:1024 * 1024
.encoding
<stringa> La codifica utilizzata per tutti gli input e output stdio. Predefinito:'buffer'
.windowsHide
<booleano> Nascondi la finestra della console del sottoprocesso che normalmente verrebbe creata sui sistemi Windows. Predefinito:false
.shell
<booleano> | <stringa> Setrue
, eseguecommand
all'interno di una shell. Usa'/bin/sh'
su Unix eprocess.env.ComSpec
su Windows. Una shell diversa può essere specificata come stringa. Vedi Requisiti della shell e Shell Windows predefinita. Predefinito:false
(nessuna shell).
Restituisce: <Buffer> | <stringa> L'output standard dal comando.
Il metodo child_process.execFileSync()
è generalmente identico a child_process.execFile()
con l'eccezione che il metodo non restituirà alcun valore fino a quando il processo figlio non sarà completamente chiuso. Quando si verifica un timeout e viene inviato killSignal
, il metodo non restituirà alcun valore finché il processo non sarà completamente terminato.
Se il processo figlio intercetta e gestisce il segnale SIGTERM
e non si chiude, il processo padre attenderà comunque fino a quando il processo figlio non si sarà chiuso.
Se il processo va in timeout o ha un codice di uscita diverso da zero, questo metodo genererà un Error
che includerà il risultato completo del sottostante child_process.spawnSync()
.
Se l'opzione shell
è abilitata, non passare input utente non sanitizzati a questa funzione. Qualsiasi input contenente metacaratteri della shell può essere utilizzato per attivare l'esecuzione di comandi arbitrari.
const { execFileSync } = require('node:child_process');
try {
const stdout = execFileSync('my-script.sh', ['my-arg'], {
// Acquisisci stdout e stderr dal processo figlio. Sovrascrive il
// comportamento predefinito dello streaming di stderr figlio all'stderr padre
stdio: 'pipe',
// Usa la codifica utf8 per le pipe stdio
encoding: 'utf8',
});
console.log(stdout);
} catch (err) {
if (err.code) {
// Generazione del processo figlio non riuscita
console.error(err.code);
} else {
// Il figlio è stato generato ma è uscito con un codice di uscita diverso da zero
// L'errore contiene qualsiasi stdout e stderr dal figlio
const { stdout, stderr } = err;
console.error({ stdout, stderr });
}
}
import { execFileSync } from 'node:child_process';
try {
const stdout = execFileSync('my-script.sh', ['my-arg'], {
// Acquisisci stdout e stderr dal processo figlio. Sovrascrive il
// comportamento predefinito dello streaming di stderr figlio all'stderr padre
stdio: 'pipe',
// Usa la codifica utf8 per le pipe stdio
encoding: 'utf8',
});
console.log(stdout);
} catch (err) {
if (err.code) {
// Generazione del processo figlio non riuscita
console.error(err.code);
} else {
// Il figlio è stato generato ma è uscito con un codice di uscita diverso da zero
// L'errore contiene qualsiasi stdout e stderr dal figlio
const { stdout, stderr } = err;
console.error({ stdout, stderr });
}
}
child_process.execSync(command[, options])
[Cronologia]
Versione | Modifiche |
---|---|
v16.4.0, v14.18.0 | L'opzione cwd può essere un oggetto URL WHATWG che utilizza il protocollo file: . |
v10.10.0 | L'opzione input ora può essere qualsiasi TypedArray o DataView . |
v8.8.0 | L'opzione windowsHide è ora supportata. |
v8.0.0 | L'opzione input ora può essere un Uint8Array . |
v0.11.12 | Aggiunto in: v0.11.12 |
command
<stringa> Il comando da eseguire.options
<Oggetto>cwd
<stringa> | <URL> Directory di lavoro corrente del processo figlio.input
<stringa> | <Buffer> | <TypedArray> | <DataView> Il valore che verrà passato come stdin al processo generato. Sestdio[0]
è impostato su'pipe'
, la fornitura di questo valore sovrascriveràstdio[0]
.stdio
<stringa> | <Array> Configurazione stdio del figlio. Vedere lostdio
dichild_process.spawn()
.stderr
per impostazione predefinita verrà inviato all'stderr del processo padre a meno che non sia specificatostdio
. Predefinito:'pipe'
.env
<Oggetto> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.shell
<stringa> Shell con cui eseguire il comando. Vedere Requisiti della shell e Shell Windows predefinita. Predefinito:'/bin/sh'
su Unix,process.env.ComSpec
su Windows.uid
<numero> Imposta l'identità dell'utente del processo. (Vederesetuid(2)
).gid
<numero> Imposta l'identità del gruppo del processo. (Vederesetgid(2)
).timeout
<numero> In millisecondi la quantità massima di tempo in cui il processo può essere eseguito. Predefinito:undefined
.killSignal
<stringa> | <intero> Il valore del segnale da utilizzare quando il processo generato verrà terminato. Predefinito:'SIGTERM'
.maxBuffer
<numero> La quantità massima di dati in byte consentita su stdout o stderr. Se superata, il processo figlio viene terminato e qualsiasi output viene troncato. Vedere l'avvertenza inmaxBuffer
e Unicode. Predefinito:1024 * 1024
.encoding
<stringa> La codifica utilizzata per tutti gli input e gli output stdio. Predefinito:'buffer'
.windowsHide
<booleano> Nasconde la finestra della console del sottoprocesso che normalmente verrebbe creata sui sistemi Windows. Predefinito:false
.
Il metodo child_process.execSync()
è generalmente identico a child_process.exec()
con l'eccezione che il metodo non restituirà nulla finché il processo figlio non sarà completamente chiuso. Quando si è verificato un timeout ed è stato inviato killSignal
, il metodo non restituirà nulla finché il processo non sarà completamente terminato. Se il processo figlio intercetta e gestisce il segnale SIGTERM
e non termina, il processo padre attenderà fino a quando il processo figlio non sarà terminato.
Se il processo scade o ha un codice di uscita diverso da zero, questo metodo genererà un'eccezione. L'oggetto Error
conterrà l'intero risultato da child_process.spawnSync()
.
Non passare mai input utente non sanitizzati a questa funzione. Qualsiasi input contenente meta caratteri della shell può essere utilizzato per attivare l'esecuzione di comandi arbitrari.
child_process.spawnSync(command[, args][, options])
[Cronologia]
Versione | Modifiche |
---|---|
v16.4.0, v14.18.0 | L'opzione cwd può essere un oggetto URL WHATWG utilizzando il protocollo file: . |
v10.10.0 | L'opzione input ora può essere qualsiasi TypedArray o DataView . |
v8.8.0 | L'opzione windowsHide è ora supportata. |
v8.0.0 | L'opzione input ora può essere un Uint8Array . |
v5.7.0 | L'opzione shell è ora supportata. |
v6.2.1, v4.5.0 | L'opzione encoding può ora essere impostata esplicitamente su buffer . |
v0.11.12 | Aggiunto in: v0.11.12 |
command
<stringa> Il comando da eseguire.args
<stringa[]> Elenco di argomenti stringa.options
<Oggetto>cwd
<stringa> | <URL> Directory di lavoro corrente del processo figlio.input
<stringa> | <Buffer> | <TypedArray> | <DataView> Il valore che verrà passato come stdin al processo generato. Sestdio[0]
è impostato su'pipe'
, la fornitura di questo valore sovrascriveràstdio[0]
.argv0
<stringa> Imposta esplicitamente il valore diargv[0]
inviato al processo figlio. Questo verrà impostato sucommand
se non specificato.stdio
<stringa> | <Array> Configurazione stdio del figlio. Consultachild_process.spawn()
'sstdio
. Predefinito:'pipe'
.env
<Oggetto> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.uid
<numero> Imposta l'identità utente del processo (vederesetuid(2)
).gid
<numero> Imposta l'identità del gruppo del processo (vederesetgid(2)
).timeout
<numero> In millisecondi la quantità massima di tempo in cui il processo può essere eseguito. Predefinito:undefined
.killSignal
<stringa> | <intero> Il valore del segnale da utilizzare quando il processo generato verrà terminato. Predefinito:'SIGTERM'
.maxBuffer
<numero> La quantità massima di dati in byte consentita su stdout o stderr. Se superata, il processo figlio viene terminato e qualsiasi output viene troncato. Vedi l'avvertenza sumaxBuffer
e Unicode. Predefinito:1024 * 1024
.encoding
<stringa> La codifica utilizzata per tutti gli input e output stdio. Predefinito:'buffer'
.shell
<booleano> | <stringa> Setrue
, eseguecommand
all'interno di una shell. Utilizza'/bin/sh'
su Unix eprocess.env.ComSpec
su Windows. È possibile specificare una shell diversa come stringa. Vedi Requisiti della shell e Shell predefinita di Windows. Predefinito:false
(nessuna shell).windowsVerbatimArguments
<booleano> Nessuna citazione o escape degli argomenti viene eseguita su Windows. Ignorato su Unix. Questo viene impostato automaticamente sutrue
quando viene specificatoshell
ed è CMD. Predefinito:false
.windowsHide
<booleano> Nasconde la finestra della console del sottoprocesso che normalmente verrebbe creata sui sistemi Windows. Predefinito:false
.
Restituisce: <Oggetto>
pid
<numero> Pid del processo figlio.output
<Array> Array di risultati dall'output stdio.stdout
<Buffer> | <stringa> Il contenuto dioutput[1]
.stderr
<Buffer> | <stringa> Il contenuto dioutput[2]
.status
<numero> | <null> Il codice di uscita del sottoprocesso onull
se il sottoprocesso è terminato a causa di un segnale.signal
<stringa> | <null> Il segnale utilizzato per terminare il sottoprocesso onull
se il sottoprocesso non è terminato a causa di un segnale.error
<Error> L'oggetto di errore se il processo figlio non è riuscito o è scaduto.
Il metodo child_process.spawnSync()
è generalmente identico a child_process.spawn()
con l'eccezione che la funzione non restituirà fino a quando il processo figlio non sarà completamente chiuso. Quando si è verificato un timeout e viene inviato killSignal
, il metodo non restituirà finché il processo non sarà uscito completamente. Se il processo intercetta e gestisce il segnale SIGTERM
e non esce, il processo padre attenderà fino a quando il processo figlio non sarà uscito.
Se l'opzione shell
è abilitata, non passare input utente non sanitizzati a questa funzione. Qualsiasi input contenente metacaratteri di shell può essere utilizzato per attivare l'esecuzione arbitraria di comandi.
Classe: ChildProcess
Aggiunto in: v2.2.0
- Estende: <EventEmitter>
Le istanze di ChildProcess
rappresentano processi figlio generati.
Non è previsto che le istanze di ChildProcess
vengano create direttamente. Invece, utilizzare i metodi child_process.spawn()
, child_process.exec()
, child_process.execFile()
o child_process.fork()
per creare istanze di ChildProcess
.
Evento: 'close'
Aggiunto in: v0.7.7
code
<number> Il codice di uscita se il processo figlio è terminato autonomamente.signal
<string> Il segnale con cui è stato terminato il processo figlio.
L'evento 'close'
viene emesso dopo che un processo è terminato e i flussi stdio di un processo figlio sono stati chiusi. Questo è diverso dall'evento 'exit'
, poiché più processi potrebbero condividere gli stessi flussi stdio. L'evento 'close'
verrà sempre emesso dopo che 'exit'
è già stato emesso, oppure 'error'
se il processo figlio non è riuscito a generarsi.
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}`);
});
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}`);
});
Evento: 'disconnect'
Aggiunto in: v0.7.2
L'evento 'disconnect'
viene emesso dopo aver chiamato il metodo subprocess.disconnect()
nel processo padre o process.disconnect()
nel processo figlio. Dopo la disconnessione, non è più possibile inviare o ricevere messaggi e la proprietà subprocess.connected
è false
.
Evento: 'error'
err
<Error> L'errore.
L'evento 'error'
viene emesso ogni volta che:
- Il processo non può essere generato.
- Il processo non può essere terminato.
- L'invio di un messaggio al processo figlio non è riuscito.
- Il processo figlio è stato interrotto tramite l'opzione
signal
.
L'evento 'exit'
può essere attivato o meno dopo che si è verificato un errore. Quando si ascoltano sia gli eventi 'exit'
che 'error'
, proteggersi dall'invocazione accidentale delle funzioni di gestione più volte.
Vedere anche subprocess.kill()
e subprocess.send()
.
Evento: 'exit'
Aggiunto in: v0.1.90
code
<number> Il codice di uscita se il processo figlio è terminato autonomamente.signal
<string> Il segnale con cui è stato terminato il processo figlio.
L'evento 'exit'
viene emesso dopo la fine del processo figlio. Se il processo è terminato, code
è il codice di uscita finale del processo, altrimenti null
. Se il processo è terminato a causa della ricezione di un segnale, signal
è il nome stringa del segnale, altrimenti null
. Uno dei due sarà sempre diverso da null
.
Quando viene attivato l'evento 'exit'
, i flussi stdio del processo figlio potrebbero essere ancora aperti.
Node.js stabilisce gestori di segnale per SIGINT
e SIGTERM
e i processi Node.js non termineranno immediatamente a causa della ricezione di tali segnali. Piuttosto, Node.js eseguirà una sequenza di azioni di pulizia e quindi rilancerà il segnale gestito.
Vedere waitpid(2)
.
Evento: 'message'
Aggiunto in: v0.5.9
message
<Object> Un oggetto JSON analizzato o un valore primitivo.sendHandle
<Handle> | <undefined>undefined
o un oggettonet.Socket
,net.Server
odgram.Socket
.
L'evento 'message'
viene attivato quando un processo figlio utilizza process.send()
per inviare messaggi.
Il messaggio passa attraverso la serializzazione e l'analisi. Il messaggio risultante potrebbe non essere lo stesso di quello inviato originariamente.
Se l'opzione serialization
è stata impostata su 'advanced'
utilizzata durante la generazione del processo figlio, l'argomento message
può contenere dati che JSON non è in grado di rappresentare. Vedere Serializzazione avanzata per maggiori dettagli.
Evento: 'spawn'
Aggiunto in: v15.1.0, v14.17.0
L'evento 'spawn'
viene emesso una volta che il processo figlio è stato generato con successo. Se il processo figlio non viene generato correttamente, l'evento 'spawn'
non viene emesso e viene emesso invece l'evento 'error'
.
Se emesso, l'evento 'spawn'
viene prima di tutti gli altri eventi e prima che qualsiasi dato venga ricevuto tramite stdout
o stderr
.
L'evento 'spawn'
si attiverà indipendentemente dal fatto che si verifichi un errore all'interno del processo generato. Ad esempio, se bash some-command
viene generato correttamente, l'evento 'spawn'
si attiverà, anche se bash
potrebbe non riuscire a generare some-command
. Questa avvertenza si applica anche quando si utilizza { shell: true }
.
subprocess.channel
[Cronologia]
Versione | Modifiche |
---|---|
v14.0.0 | L'oggetto non espone più accidentalmente i binding C++ nativi. |
v7.1.0 | Aggiunto in: v7.1.0 |
- <Object> Una pipe che rappresenta il canale IPC verso il processo figlio.
La proprietà subprocess.channel
è un riferimento al canale IPC del figlio. Se non esiste alcun canale IPC, questa proprietà è undefined
.
subprocess.channel.ref()
Aggiunto in: v7.1.0
Questo metodo fa sì che il canale IPC mantenga in esecuzione il ciclo di eventi del processo padre se .unref()
è stato chiamato in precedenza.
subprocess.channel.unref()
Aggiunto in: v7.1.0
Questo metodo fa sì che il canale IPC non mantenga in esecuzione il ciclo di eventi del processo padre e gli consente di terminare anche mentre il canale è aperto.
subprocess.connected
Aggiunto in: v0.7.2
- <boolean> Impostato su
false
dopo che è stato chiamatosubprocess.disconnect()
.
La proprietà subprocess.connected
indica se è ancora possibile inviare e ricevere messaggi da un processo figlio. Quando subprocess.connected
è false
, non è più possibile inviare o ricevere messaggi.
subprocess.disconnect()
Aggiunto in: v0.7.2
Chiude il canale IPC tra processi padre e figlio, consentendo al processo figlio di uscire normalmente una volta che non ci sono altre connessioni che lo mantengono attivo. Dopo aver chiamato questo metodo, le proprietà subprocess.connected
e process.connected
sia nel processo padre che nel processo figlio (rispettivamente) saranno impostate su false
e non sarà più possibile passare messaggi tra i processi.
L'evento 'disconnect'
verrà emesso quando non ci sono messaggi in fase di ricezione. Questo verrà molto spesso attivato immediatamente dopo aver chiamato subprocess.disconnect()
.
Quando il processo figlio è un'istanza di Node.js (ad esempio, generata usando child_process.fork()
), il metodo process.disconnect()
può essere invocato all'interno del processo figlio per chiudere anche il canale IPC.
subprocess.exitCode
La proprietà subprocess.exitCode
indica il codice di uscita del processo figlio. Se il processo figlio è ancora in esecuzione, il campo sarà null
.
subprocess.kill([signal])
Aggiunto in: v0.1.90
Il metodo subprocess.kill()
invia un segnale al processo figlio. Se non viene fornito alcun argomento, al processo verrà inviato il segnale 'SIGTERM'
. Vedere signal(7)
per un elenco dei segnali disponibili. Questa funzione restituisce true
se kill(2)
ha esito positivo e false
in caso contrario.
const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);
grep.on('close', (code, signal) => {
console.log(
`child process terminated due to receipt of signal ${signal}`);
});
// Send SIGHUP to process.
grep.kill('SIGHUP');
import { spawn } from 'node:child_process';
const grep = spawn('grep', ['ssh']);
grep.on('close', (code, signal) => {
console.log(
`child process terminated due to receipt of signal ${signal}`);
});
// Send SIGHUP to process.
grep.kill('SIGHUP');
L'oggetto ChildProcess
può emettere un evento 'error'
se il segnale non può essere recapitato. L'invio di un segnale a un processo figlio che è già terminato non è un errore, ma può avere conseguenze impreviste. In particolare, se l'identificatore del processo (PID) è stato riassegnato a un altro processo, il segnale verrà recapitato a quel processo, il che può avere risultati inattesi.
Sebbene la funzione sia chiamata kill
, il segnale recapitato al processo figlio potrebbe non terminare effettivamente il processo.
Vedere kill(2)
per riferimento.
Su Windows, dove i segnali POSIX non esistono, l'argomento signal
verrà ignorato tranne che per 'SIGKILL'
, 'SIGTERM'
, 'SIGINT'
e 'SIGQUIT'
, e il processo verrà sempre terminato con forza e bruscamente (simile a 'SIGKILL'
). Vedere Eventi di segnale per maggiori dettagli.
Su Linux, i processi figlio dei processi figlio non verranno terminati quando si tenta di terminare il loro padre. È probabile che ciò accada quando si esegue un nuovo processo in una shell o con l'uso dell'opzione shell
di ChildProcess
:
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(); // Does not terminate the Node.js process in the shell.
}, 2000);
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(); // Does not terminate the Node.js process in the shell.
}, 2000);
subprocess[Symbol.dispose]()
Aggiunto in: v20.5.0, v18.18.0
[Stabile: 1 - Sperimentale]
Stabile: 1 Stabilità: 1 - Sperimentale
Chiama subprocess.kill()
con 'SIGTERM'
.
subprocess.killed
Aggiunto in: v0.5.10
- <boolean> Impostato su
true
dopo chesubprocess.kill()
viene utilizzato per inviare con successo un segnale al processo figlio.
La proprietà subprocess.killed
indica se il processo figlio ha ricevuto con successo un segnale da subprocess.kill()
. La proprietà killed
non indica che il processo figlio è stato terminato.
subprocess.pid
Aggiunto in: v0.1.90
Restituisce l'identificativo del processo (PID) del processo figlio. Se il processo figlio non riesce a generarsi a causa di errori, allora il valore è undefined
e viene emesso error
.
const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);
console.log(`PID del figlio generato: ${grep.pid}`);
grep.stdin.end();
import { spawn } from 'node:child_process';
const grep = spawn('grep', ['ssh']);
console.log(`PID del figlio generato: ${grep.pid}`);
grep.stdin.end();
subprocess.ref()
Aggiunto in: v0.7.10
Chiamare subprocess.ref()
dopo aver effettuato una chiamata a subprocess.unref()
ripristinerà il conteggio dei riferimenti rimosso per il processo figlio, forzando il processo padre ad attendere che il processo figlio esca prima di uscire a sua volta.
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();
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])
[Cronologia]
Versione | Modifiche |
---|---|
v5.8.0 | Il parametro options , e in particolare l'opzione keepOpen , è ora supportato. |
v5.0.0 | Questo metodo ora restituisce un booleano per il controllo del flusso. |
v4.0.0 | Il parametro callback è ora supportato. |
v0.5.9 | Aggiunto in: v0.5.9 |
message
<Object>sendHandle
<Handle> | <undefined>undefined
, oppure un oggettonet.Socket
,net.Server
, odgram.Socket
.options
<Object> L'argomentooptions
, se presente, è un oggetto utilizzato per parametrizzare l'invio di determinati tipi di handle.options
supporta le seguenti proprietà:keepOpen
<boolean> Un valore che può essere utilizzato quando si passano istanze dinet.Socket
. Quandotrue
, il socket viene mantenuto aperto nel processo di invio. Predefinito:false
.
callback
<Function>Restituisce: <boolean>
Quando è stato stabilito un canale IPC tra il processo padre e quello figlio (ovvero quando si utilizza child_process.fork()
), il metodo subprocess.send()
può essere utilizzato per inviare messaggi al processo figlio. Quando il processo figlio è un'istanza di Node.js, questi messaggi possono essere ricevuti tramite l'evento 'message'
.
Il messaggio passa attraverso la serializzazione e l'analisi. Il messaggio risultante potrebbe non essere lo stesso di quello inviato originariamente.
Ad esempio, nello script padre:
const { fork } = require('node:child_process');
const forkedProcess = fork(`${__dirname}/sub.js`);
forkedProcess.on('message', (message) => {
console.log('PARENT got message:', message);
});
// Fa sì che il figlio stampi: CHILD got message: { hello: 'world' }
forkedProcess.send({ hello: 'world' });
import { fork } from 'node:child_process';
const forkedProcess = fork(`${import.meta.dirname}/sub.js`);
forkedProcess.on('message', (message) => {
console.log('PARENT got message:', message);
});
// Fa sì che il figlio stampi: CHILD got message: { hello: 'world' }
forkedProcess.send({ hello: 'world' });
E quindi lo script figlio, 'sub.js'
potrebbe apparire così:
process.on('message', (message) => {
console.log('CHILD got message:', message);
});
// Fa sì che il padre stampi: PARENT got message: { foo: 'bar', baz: null }
process.send({ foo: 'bar', baz: NaN });
I processi figlio di Node.js avranno un metodo process.send()
proprio che consente al processo figlio di inviare messaggi al processo padre.
C'è un caso speciale quando si invia un messaggio {cmd: 'NODE_foo'}
. I messaggi contenenti un prefisso NODE_
nella proprietà cmd
sono riservati per l'uso all'interno del core di Node.js e non verranno emessi nell'evento 'message'
del figlio. Piuttosto, tali messaggi vengono emessi utilizzando l'evento 'internalMessage'
e vengono consumati internamente da Node.js. Le applicazioni dovrebbero evitare di utilizzare tali messaggi o di ascoltare gli eventi 'internalMessage'
poiché sono soggetti a modifiche senza preavviso.
L'argomento opzionale sendHandle
che può essere passato a subprocess.send()
serve per passare un server TCP o un oggetto socket al processo figlio. Il processo figlio riceverà l'oggetto come secondo argomento passato alla funzione di callback registrata sull'evento 'message'
. Tutti i dati ricevuti e memorizzati nel buffer nel socket non verranno inviati al figlio. L'invio di socket IPC non è supportato su Windows.
La callback
opzionale è una funzione che viene richiamata dopo che il messaggio è stato inviato ma prima che il processo figlio possa averlo ricevuto. La funzione viene chiamata con un singolo argomento: null
in caso di successo oppure un oggetto Error
in caso di errore.
Se non viene fornita alcuna funzione callback
e il messaggio non può essere inviato, verrà emesso un evento 'error'
dall'oggetto ChildProcess
. Questo può accadere, ad esempio, quando il processo figlio è già uscito.
subprocess.send()
restituirà false
se il canale è stato chiuso o quando il backlog di messaggi non inviati supera una soglia che rende imprudente inviarne altri. Altrimenti, il metodo restituisce true
. La funzione callback
può essere utilizzata per implementare il controllo del flusso.
Esempio: invio di un oggetto server
L'argomento sendHandle
può essere utilizzato, ad esempio, per passare l'handle di un oggetto server TCP al processo figlio come illustrato nell'esempio seguente:
const { fork } = require('node:child_process');
const { createServer } = require('node:net');
const subprocess = fork('subprocess.js');
// Apri l'oggetto server e invia l'handle.
const server = createServer();
server.on('connection', (socket) => {
socket.end('gestito dal padre');
});
server.listen(1337, () => {
subprocess.send('server', server);
});
import { fork } from 'node:child_process';
import { createServer } from 'node:net';
const subprocess = fork('subprocess.js');
// Apri l'oggetto server e invia l'handle.
const server = createServer();
server.on('connection', (socket) => {
socket.end('gestito dal padre');
});
server.listen(1337, () => {
subprocess.send('server', server);
});
Il processo figlio riceverebbe quindi l'oggetto server come:
process.on('message', (m, server) => {
if (m === 'server') {
server.on('connection', (socket) => {
socket.end('gestito dal figlio');
});
}
});
Una volta che il server è condiviso tra il processo padre e figlio, alcune connessioni possono essere gestite dal padre e altre dal figlio.
Mentre l'esempio precedente utilizza un server creato utilizzando il modulo node:net
, i server del modulo node:dgram
utilizzano esattamente lo stesso flusso di lavoro con le eccezioni dell'ascolto di un evento 'message'
invece di 'connection'
e dell'utilizzo di server.bind()
invece di server.listen()
. Questo, tuttavia, è supportato solo su piattaforme Unix.
Esempio: invio di un oggetto socket
Allo stesso modo, l'argomento sendHandler
può essere utilizzato per passare l'handle di un socket al processo figlio. L'esempio seguente genera due processi figli che gestiscono ciascuno le connessioni con priorità "normale" o "speciale":
const { fork } = require('node:child_process');
const { createServer } = require('node:net');
const normal = fork('subprocess.js', ['normal']);
const special = fork('subprocess.js', ['special']);
// Apri il server e invia i socket al figlio. Usa pauseOnConnect per impedire
// che i socket vengano letti prima di essere inviati al processo figlio.
const server = createServer({ pauseOnConnect: true });
server.on('connection', (socket) => {
// Se questa è una priorità speciale...
if (socket.remoteAddress === '74.125.127.100') {
special.send('socket', socket);
return;
}
// Questa è una priorità normale.
normal.send('socket', socket);
});
server.listen(1337);
import { fork } from 'node:child_process';
import { createServer } from 'node:net';
const normal = fork('subprocess.js', ['normal']);
const special = fork('subprocess.js', ['special']);
// Apri il server e invia i socket al figlio. Usa pauseOnConnect per impedire
// che i socket vengano letti prima di essere inviati al processo figlio.
const server = createServer({ pauseOnConnect: true });
server.on('connection', (socket) => {
// Se questa è una priorità speciale...
if (socket.remoteAddress === '74.125.127.100') {
special.send('socket', socket);
return;
}
// Questa è una priorità normale.
normal.send('socket', socket);
});
server.listen(1337);
subprocess.js
riceverebbe l'handle del socket come secondo argomento passato alla funzione di callback dell'evento:
process.on('message', (m, socket) => {
if (m === 'socket') {
if (socket) {
// Controlla che il socket client esista.
// È possibile che il socket venga chiuso tra il momento in cui viene
// inviato e il momento in cui viene ricevuto nel processo figlio.
socket.end(`Richiesta gestita con priorità ${process.argv[2]}`);
}
}
});
Non usare .maxConnections
su un socket che è stato passato a un subprocesso. Il padre non può tracciare quando il socket viene distrutto.
Qualsiasi gestore 'message'
nel subprocesso deve verificare che socket
esista, poiché la connessione potrebbe essere stata chiusa durante il tempo necessario per inviare la connessione al figlio.
subprocess.signalCode
La proprietà subprocess.signalCode
indica il segnale ricevuto dal processo figlio, se presente, altrimenti null
.
subprocess.spawnargs
La proprietà subprocess.spawnargs
rappresenta l'elenco completo degli argomenti della riga di comando con cui è stato avviato il processo figlio.
subprocess.spawnfile
La proprietà subprocess.spawnfile
indica il nome del file eseguibile del processo figlio avviato.
Per child_process.fork()
, il suo valore sarà uguale a process.execPath
. Per child_process.spawn()
, il suo valore sarà il nome del file eseguibile. Per child_process.exec()
, il suo valore sarà il nome della shell in cui viene avviato il processo figlio.
subprocess.stderr
Aggiunto in: v0.1.90
Un Readable Stream
che rappresenta lo stderr
del processo figlio.
Se il processo figlio è stato generato con stdio[2]
impostato su qualcosa di diverso da 'pipe'
, allora questo sarà null
.
subprocess.stderr
è un alias per subprocess.stdio[2]
. Entrambe le proprietà faranno riferimento allo stesso valore.
La proprietà subprocess.stderr
può essere null
o undefined
se il processo figlio non è stato generato correttamente.
subprocess.stdin
Aggiunto in: v0.1.90
Uno Stream Writable
che rappresenta lo stdin
del processo figlio.
Se un processo figlio attende di leggere tutto il suo input, il processo figlio non continuerà finché questo stream non sarà stato chiuso tramite end()
.
Se il processo figlio è stato generato con stdio[0]
impostato su qualcosa di diverso da 'pipe'
, allora questo sarà null
.
subprocess.stdin
è un alias per subprocess.stdio[0]
. Entrambe le proprietà si riferiranno allo stesso valore.
La proprietà subprocess.stdin
può essere null
o undefined
se il processo figlio non è stato generato con successo.
subprocess.stdio
Aggiunto in: v0.7.10
Un array sparso di pipe al processo figlio, corrispondenti alle posizioni nell'opzione stdio
passata a child_process.spawn()
che sono state impostate sul valore 'pipe'
. subprocess.stdio[0]
, subprocess.stdio[1]
e subprocess.stdio[2]
sono disponibili anche come subprocess.stdin
, subprocess.stdout
e subprocess.stderr
, rispettivamente.
Nell'esempio seguente, solo il fd 1
(stdout) del figlio è configurato come una pipe, quindi solo il subprocess.stdio[1]
del genitore è uno stream, tutti gli altri valori nell'array sono null
.
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, // Usa stdin del genitore per il figlio.
'pipe', // Invia stdout del figlio al genitore tramite pipe.
fs.openSync('err.out', 'w'), // Invia stderr del figlio a un 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);
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, // Usa stdin del genitore per il figlio.
'pipe', // Invia stdout del figlio al genitore tramite pipe.
fs.openSync('err.out', 'w'), // Invia stderr del figlio a un 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);
La proprietà subprocess.stdio
può essere undefined
se il processo figlio non è stato generato con successo.
subprocess.stdout
Aggiunto in: v0.1.90
Uno Stream Leggibile
che rappresenta stdout
del processo figlio.
Se il processo figlio è stato generato con stdio[1]
impostato su un valore diverso da 'pipe'
, allora questo sarà null
.
subprocess.stdout
è un alias per subprocess.stdio[1]
. Entrambe le proprietà faranno riferimento allo stesso valore.
const { spawn } = require('node:child_process');
const subprocess = spawn('ls');
subprocess.stdout.on('data', (data) => {
console.log(`Received chunk ${data}`);
});
import { spawn } from 'node:child_process';
const subprocess = spawn('ls');
subprocess.stdout.on('data', (data) => {
console.log(`Received chunk ${data}`);
});
La proprietà subprocess.stdout
può essere null
o undefined
se il processo figlio non può essere generato correttamente.
subprocess.unref()
Aggiunto in: v0.7.10
Per impostazione predefinita, il processo padre attenderà l'uscita del processo figlio disaccoppiato. Per evitare che il processo padre attenda l'uscita di una determinata subprocess
, utilizzare il metodo subprocess.unref()
. In questo modo, il ciclo di eventi del padre non includerà il processo figlio nel suo conteggio dei riferimenti, consentendo al padre di uscire indipendentemente dal figlio, a meno che non esista un canale IPC stabilito tra il figlio e i processi padre.
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();
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
e Unicode
L'opzione maxBuffer
specifica il numero massimo di byte consentiti su stdout
o stderr
. Se questo valore viene superato, il processo figlio viene terminato. Ciò influisce sull'output che include codifiche di caratteri multibyte come UTF-8 o UTF-16. Ad esempio, console.log('中文测试')
invierà 13 byte codificati in UTF-8 a stdout
sebbene ci siano solo 4 caratteri.
Requisiti della shell
La shell dovrebbe capire l'interruttore -c
. Se la shell è 'cmd.exe'
, dovrebbe capire gli interruttori /d /s /c
e l'analisi della riga di comando dovrebbe essere compatibile.
Shell predefinita di Windows
Sebbene Microsoft specifichi che %COMSPEC%
deve contenere il percorso di 'cmd.exe'
nell'ambiente radice, i processi figlio non sono sempre soggetti allo stesso requisito. Pertanto, nelle funzioni child_process
in cui è possibile generare una shell, viene utilizzato 'cmd.exe'
come fallback se process.env.ComSpec
non è disponibile.
Serializzazione avanzata
Aggiunto in: v13.2.0, v12.16.0
I processi figlio supportano un meccanismo di serializzazione per IPC basato sull'API di serializzazione del modulo node:v8
, basato sull'algoritmo di clonazione strutturata HTML. Questo è generalmente più potente e supporta più tipi di oggetti JavaScript integrati, come BigInt
, Map
e Set
, ArrayBuffer
e TypedArray
, Buffer
, Error
, RegExp
ecc.
Tuttavia, questo formato non è un superset completo di JSON e, ad esempio, le proprietà impostate su oggetti di tali tipi integrati non verranno passate attraverso il passaggio di serializzazione. Inoltre, le prestazioni potrebbero non essere equivalenti a quelle di JSON, a seconda della struttura dei dati passati. Pertanto, questa funzionalità richiede l'adesione impostando l'opzione serialization
su 'advanced'
quando si chiama child_process.spawn()
o child_process.fork()
.