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 modo simile, ma non identico, a popen(3)
. Questa funzionalità è 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, vengono stabiliti dei pipe per stdin
, stdout
e stderr
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 acquisito, il sottoprocesso si blocca in attesa che il buffer del pipe accetti più dati. Questo comportamento è identico a quello dei pipe nella shell. Utilizzare l'opzione { stdio: 'ignore' }
se l'output non verrà utilizzato.
La ricerca del comando viene eseguita utilizzando la variabile di ambiente options.env.PATH
se env
è 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 /usr/bin:/bin
(consultare il manuale del proprio sistema operativo per execvpe/execvp), su Windows viene utilizzata la variabile di ambiente PATH
del processo corrente.
Su Windows, le variabili di ambiente non fanno distinzione tra maiuscole e minuscole. Node.js ordina lessicograficamente le chiavi env
e utilizza la prima che corrisponde in modo insensibile al caso. 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 una funzionalità equivalente in modo sincrono che blocca il ciclo di eventi finché il processo generato non termina o viene interrotto.
Per comodità, il modulo node:child_process
fornisce una serie di alternative sincrone e asincrone a child_process.spawn()
e child_process.spawnSync()
. Ciascuna di queste alternative è implementata sulla base di child_process.spawn()
o child_process.spawnSync()
.
child_process.exec()
: genera una shell ed esegue un comando all'interno di quella 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 il padre e il 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 sincrone potrebbero 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 di processi asincroni
I metodi child_process.spawn()
, child_process.fork()
, child_process.exec()
e child_process.execFile()
seguono tutti il modello di programmazione asincrona idiomatico tipico delle altre API di Node.js.
Ciascuno dei metodi restituisce un'istanza ChildProcess
. Questi oggetti implementano l'API EventEmitter
di Node.js, consentendo al processo padre di registrare funzioni 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()
oppure generando cmd.exe
e passando il file .bat
o .cmd
come argomento (che è quello che fanno l'opzione shell
e child_process.exec()
). In ogni caso, se il nome del file di script contiene spazi, deve essere racchiuso tra virgolette.
// O...
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 file:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true })
// o:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
// ...
})
// O...
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 file:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true })
// o:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
// ...
})
child_process.exec(command[, options][, callback])
[Cronologia]
Versione | Modifiche |
---|---|
v15.4.0 | 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 | Ora è supportata l'opzione windowsHide . |
v0.1.90 | Aggiunto in: v0.1.90 |
command
<stringa> Il comando da eseguire, con argomenti separati da spazi.options
<Oggetto>cwd
<stringa> | <URL> Directory di lavoro corrente del processo figlio. Predefinito:process.cwd()
.env
<Oggetto> 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 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> | <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 verrebbe normalmente creata sui sistemi Windows. Predefinito:false
.
callback
<Funzione> chiamata con l'output quando il processo termina.Restituisce: <ChildProcess>
Avvia una shell quindi esegue il comando
all'interno di tale shell, memorizzando l'output generato. La stringa comando
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 viene protetta nel primo caso, ma non nel secondo.
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 viene protetta nel primo caso, ma non nel secondo.
Non passare mai input utente non sanificato a questa funzione. Qualsiasi input contenente metacaratteri della shell può essere utilizzato per attivare l'esecuzione di comandi arbitrari.
Se viene fornita una funzione callback
, questa viene chiamata con gli argomenti (error, stdout, stderr)
. In caso di successo, error
sarà null
. In caso di errore, error
sarà un'istanza di Errore
. 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 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 passati alla callback.
const { exec } = require('node:child_process')
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
if (error) {
console.error(`errore di esecuzione: ${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(`errore di esecuzione: ${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 la sua versione util.promisify()
ed, restituisce una Promise
per un Oggetto
con le proprietà stdout
e stderr
. L'istanza ChildProcess
restituita è allegata alla Promise
come proprietà child
. In caso di errore (incluso qualsiasi errore che comporta 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 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 alla 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) // un 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) // un AbortError
})
controller.abort()
child_process.execFile(file[, args][, options][, callback])
[Cronologia]
Versione | Cambiamenti |
---|---|
v16.4.0, v14.18.0 | L'opzione cwd può essere un oggetto WHATWG URL usando il protocollo file: . |
v15.4.0, v14.17.0 | 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 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. Consulta l'avvertenza inmaxBuffer
e Unicode. Predefinito:1024 * 1024
.killSignal
<stringa> | <intero> Predefinito:'SIGTERM'
uid
<numero> Imposta l'identità utente del processo (vedisetuid(2)
).gid
<numero> Imposta l'identità di gruppo del processo (vedisetgid(2)
).windowsHide
<booleano> Nasconde la finestra della console del sottoprocesso che normalmente verrebbe creata sui sistemi Windows. Predefinito:false
.windowsVerbatimArguments
<booleano> Nessuna virgolettatura 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. Consulta 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, l'eseguibile file
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é non viene generata una shell, comportamenti come il reindirizzamento I/O e il globbing di file 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 passati invece alla callback.
Se questo metodo viene richiamato come versione con util.promisify()
, restituisce una Promise
per un Object
con le proprietà stdout
e stderr
. L'istanza ChildProcess
restituita è allegata alla Promise
come proprietà child
. In caso di errore (compreso qualsiasi errore derivante da 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 sanitizzati a questa funzione. Qualsiasi input contenente metacaratteri di shell può essere utilizzato per attivare l'esecuzione arbitraria di comandi.
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) // un 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) // un 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 utilizzando il protocollo file: . |
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 | Aggiunto il timeout. |
v15.11.0, v14.18.0 | Aggiunto killSignal per AbortSignal. |
v15.6.0, v14.17.0 | 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
<string> | <URL> Il modulo da eseguire nel figlio.args
<string[]> Elenco di argomenti stringa.options
<Object>cwd
<string> | <URL> Directory di lavoro corrente del processo figlio.detached
<boolean> Prepara il processo figlio per essere eseguito in modo indipendente dal processo padre. Il comportamento specifico dipende dalla piattaforma, vedioptions.detached
).env
<Object> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.execPath
<string> Eseguibile utilizzato per creare il processo figlio.execArgv
<string[]> Elenco di argomenti stringa passati all'eseguibile. Predefinito:process.execArgv
.gid
<number> Imposta l'identità del gruppo del processo (vedisetgid(2)
).serialization
<string> Specifica il tipo di serializzazione utilizzata per l'invio di messaggi tra i processi. I valori possibili sono'json'
e'advanced'
. Per maggiori dettagli, vedi Serializzazione avanzata. Predefinito:'json'
.signal
<AbortSignal> Consente la chiusura del processo figlio utilizzando un AbortSignal.killSignal
<string> | <integer> Il valore del segnale da utilizzare quando il processo generato verrà terminato dal timeout o dal segnale di interruzione. Predefinito:'SIGTERM'
.silent
<boolean> Setrue
, stdin, stdout e stderr del processo figlio verranno indirizzati al processo padre, altrimenti verranno ereditati dal processo padre, vedi le opzioni'pipe'
e'inherit'
perchild_process.spawn()
'sstdio
per maggiori dettagli. Predefinito:false
.stdio
<Array> | <string> Vedistdio
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
<number> Imposta l'identità utente del processo (vedisetuid(2)
).windowsVerbatimArguments
<boolean> Nessuna citazione o escape degli argomenti viene eseguita su Windows. Ignorato su Unix. Predefinito:false
.timeout
<number> In millisecondi la quantità massima di tempo consentita per l'esecuzione del processo. 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 incorporato che consente di passare messaggi avanti e indietro tra il padre e il figlio. Per i dettagli, vedi subprocess.send()
.
Tieni presente che i processi figlio 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 gran numero di processi figlio 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 d'ambiente NODE_CHANNEL_FD
sul processo figlio.
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 AbortController
corrispondente è simile a chiamare .kill()
sul processo figlio, ad eccezione del 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(`Ciao da ${process.argv[2]}!`)
}, 1_000)
} else {
const controller = new AbortController()
const { signal } = controller
const child = fork(__filename, ['child'], { signal })
child.on('error', err => {
// Questo verrà chiamato con err come AbortError se il controller si interrompe
})
controller.abort() // Ferma il processo figlio
}
import { fork } from 'node:child_process'
import process from 'node:process'
if (process.argv[2] === 'child') {
setTimeout(() => {
console.log(`Ciao da ${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 => {
// Questo verrà chiamato con err come AbortError se il controller si interrompe
})
controller.abort() // Ferma il processo figlio
}
child_process.spawn(command[, args][, options])
[Cronologia]
Versione | Cambiamenti |
---|---|
v16.4.0, v14.18.0 | L'opzione cwd può essere un oggetto URL WHATWG usando 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.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
<string> Il comando da eseguire.args
<string[]> Elenco di argomenti stringa.options
<Object>cwd
<string> | <URL> Directory di lavoro corrente del processo figlio.env
<Object> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.argv0
<string> Imposta esplicitamente il valore diargv[0]
inviato al processo figlio. Questo sarà impostato sucommand
se non specificato.stdio
<Array> | <string> Configurazione stdio del figlio (vedioptions.stdio
).detached
<boolean> Prepara il processo figlio per l'esecuzione indipendente dal suo processo padre. Il comportamento specifico dipende dalla piattaforma, vedioptions.detached
).uid
<number> Imposta l'identità utente del processo (vedisetuid(2)
).gid
<number> Imposta l'identità di gruppo del processo (vedisetgid(2)
).serialization
<string> Specifica il tipo di serializzazione utilizzato per l'invio di messaggi tra processi. I valori possibili sono'json'
e'advanced'
. Vedi Serializzazione avanzata per maggiori dettagli. Predefinito:'json'
.shell
<boolean> | <string> 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).windowsVerbatimArguments
<boolean> Nessuna virgolettatura o escape degli argomenti viene effettuata su Windows. Ignorato su Unix. Questo viene impostato automaticamente sutrue
quando viene specificata unashell
ed è CMD. Predefinito:false
.windowsHide
<boolean> Nasconde 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
<number> In millisecondi, il tempo massimo consentito per l'esecuzione del processo. Predefinito:undefined
.killSignal
<string> | <integer> Il valore del segnale da utilizzare quando il processo generato verrà interrotto da timeout o segnale di interruzione. Predefinito:'SIGTERM'
.
Restituisce: <ChildProcess>
Il metodo child_process.spawn()
genera un nuovo processo usando il command
dato, con argomenti della riga di comando in args
. Se omesso, args
assume come valore predefinito un array vuoto.
Se l'opzione shell
è abilitata, non passare input utente non filtrato a questa funzione. Qualsiasi input contenente metacaratteri della shell potrebbe essere usato per attivare l'esecuzione arbitraria di comandi.
Un terzo argomento può essere usato per specificare opzioni aggiuntive, con questi valori predefiniti:
const defaults = {
cwd: undefined,
env: process.env,
}
Usa cwd
per specificare la directory di lavoro da cui viene generato il processo. Se non specificato, il valore predefinito è quello di ereditare la directory di lavoro corrente. Se specificato, ma il percorso non esiste, il processo figlio emette un errore ENOENT
ed esce immediatamente. ENOENT
viene emesso anche quando il comando non esiste.
Usa env
per specificare le variabili d'ambiente che saranno visibili al nuovo processo, il valore predefinito è process.env
.
I valori undefined
in env
saranno ignorati.
Esempio di esecuzione di ls -lh /usr
, cattura di stdout
, stderr
e del 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 controllo di un spawn
fallito:
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.')
})
Certe 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 corrispondente AbortController
è 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 => {
// Questo verrà chiamato con err che è un AbortError se il controller si interrompe
})
controller.abort() // Ferma il processo figlio
import { spawn } from 'node:child_process'
const controller = new AbortController()
const { signal } = controller
const grep = spawn('grep', ['ssh'], { signal })
grep.on('error', err => {
// Questo verrà chiamato con err che è un AbortError se il controller si interrompe
})
controller.abort() // Ferma il processo figlio
options.detached
Aggiunto in: v0.7.10
Su Windows, impostare options.detached
su true
consente al processo figlio di continuare a essere eseguito dopo l'uscita dal processo padre. Il processo figlio avrà la propria finestra della console. Una volta abilitato per un processo figlio, non può essere disabilitato.
Sulle piattaforme non Windows, se options.detached
è impostato su true
, il processo figlio sarà reso il leader di un nuovo gruppo di processi e sessione. I processi figlio possono continuare a essere eseguiti dopo l'uscita del processo padre indipendentemente dal fatto che siano scollegati o meno. Per maggiori informazioni, consultare setsid(2)
.
Per impostazione predefinita, il processo padre attenderà l'uscita del processo figlio scollegato. Per impedire che il processo padre attenda l'uscita di un determinato subprocess
, utilizzare il metodo subprocess.unref()
. In questo modo, il ciclo di eventi del processo padre non includerà il processo figlio nel conteggio dei riferimenti, consentendo al processo padre di uscire indipendentemente dal processo figlio, a meno che non sia presente un canale IPC stabilito tra il figlio e il processo padre.
Quando si utilizza l'opzione detached
per avviare un processo a esecuzione prolungata, il processo non continuerà a essere eseguito in background dopo l'uscita del processo padre, a meno che non sia fornita una configurazione stdio
non collegata al processo padre. Se stdio
del processo padre viene ereditato, il processo figlio rimarrà collegato al terminale di controllo.
Esempio di processo a esecuzione prolungata, mediante scollegamento e ignorando anche i descrittori di file stdio
del processo padre, al fine di ignorare la terminazione del 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, è possibile 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 stabiliti tra il processo padre e quello figlio. Per impostazione predefinita, stdin, stdout e stderr del figlio vengono reindirizzati ai corrispondenti flussi subprocess.stdin
, subprocess.stdout
e subprocess.stderr
sull'oggetto ChildProcess
. Questo 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']
(l'impostazione predefinita)'overlapped'
: equivalente a['overlapped', 'overlapped', 'overlapped']
'ignore'
: equivalente a['ignore', 'ignore', 'ignore']
'inherit'
: equivalente a['inherit', 'inherit', 'inherit']
o[0, 1, 2]
Altrimenti, il valore di options.stdio
è un array in cui ogni indice corrisponde a un fd nel figlio. I fd 0, 1 e 2 corrispondono rispettivamente a stdin, stdout e stderr. È possibile specificare fd aggiuntivi per creare pipe aggiuntivi tra il padre e il figlio. Il valore è uno dei seguenti:
const { spawn } = require('node:child_process')
const process = require('node:process')
// Il figlio userà gli stdio del padre.
spawn('prg', [], { stdio: 'inherit' })
// Genera un figlio condividendo solo stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] })
// Apri un fd=4 extra per interagire con i 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 userà gli stdio del padre.
spawn('prg', [], { stdio: 'inherit' })
// Genera un figlio condividendo solo stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] })
// Apri un fd=4 extra per interagire con i programmi che presentano
// un'interfaccia in stile startd.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] })
È importante notare che quando viene stabilito un canale IPC tra il processo padre e quello figlio, e il processo figlio è un'istanza di Node.js, il processo figlio viene avviato con il canale IPC non referenziato (usando 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 uscire normalmente senza che il processo venga mantenuto aperto dal canale IPC aperto. Vedere anche: child_process.exec()
e child_process.fork()
.
Creazione di processi sincroni
I metodi child_process.spawnSync()
, child_process.execSync()
e child_process.execFileSync()
sono sincroni e bloccheranno il ciclo di eventi di Node.js, mettendo in pausa l'esecuzione di qualsiasi codice aggiuntivo fino a quando il processo generato non termina.
Le chiamate bloccanti come queste sono utili principalmente per semplificare le attività di scripting di uso generale 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 WHATWG URL che utilizza il protocollo file: . |
v10.10.0 | L'opzione input può ora essere qualsiasi TypedArray o DataView . |
v8.8.0 | L'opzione windowsHide è ora supportata. |
v8.0.0 | L'opzione input può ora essere un Uint8Array . |
v6.2.1, v4.5.0 | L'opzione encoding può ora essere impostata esplicitamente su buffer . |
v0.11.12 | Aggiunto in: v0.11.12 |
file
<string> Il nome o il percorso del file eseguibile da eseguire.args
<string[]> Elenco degli argomenti stringa.options
<Object>cwd
<string> | <URL> Directory di lavoro corrente del processo figlio.input
<string> | <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
<string> | <Array> Configurazione stdio del figlio. Vederechild_process.spawn()
'sstdio
. Per impostazione predefinita,stderr
verrà emesso nell'stderr del processo padre a meno che non venga specificatostdio
. Predefinito:'pipe'
.env
<Object> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.uid
<number> Imposta l'identità dell'utente del processo (vederesetuid(2)
).gid
<number> Imposta l'identità del gruppo del processo (vederesetgid(2)
).timeout
<number> In millisecondi, il tempo massimo in cui il processo può essere eseguito. Predefinito:undefined
.killSignal
<string> | <integer> Il valore del segnale da utilizzare quando il processo generato verrà terminato. Predefinito:'SIGTERM'
.maxBuffer
<number> La massima quantità di dati in byte consentita su stdout o stderr. Se superata, il processo figlio viene terminato. Vedere l'avvertenza inmaxBuffer
e Unicode. Predefinito:1024 * 1024
.encoding
<string> La codifica utilizzata per tutti gli input e gli output stdio. Predefinito:'buffer'
.windowsHide
<boolean> Nasconde la finestra della console del sottoprocesso che verrebbe normalmente creata nei sistemi Windows. Predefinito:false
.shell
<boolean> | <string> 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. Vedere Requisiti della shell e Shell predefinita di Windows. Predefinito:false
(nessuna shell).
Il metodo child_process.execFileSync()
è generalmente identico a child_process.execFile()
con l'eccezione che il metodo non restituirà alcun valore finché il processo figlio non si sarà chiuso completamente. Quando si è verificato un timeout e viene inviato killSignal
, il metodo non restituisce alcun valore finché il processo non è terminato completamente.
Se il processo figlio intercetta e gestisce il segnale SIGTERM
e non termina, il processo padre attenderà comunque 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 Error
che includerà il risultato completo del sottostante child_process.spawnSync()
.
Se l'opzione shell
è abilitata, non passare input utente non sanificati 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'], {
// Acquisisce stdout e stderr dal processo figlio. Sovrascrive il
// comportamento predefinito di invio in streaming dell'stderr del figlio all'stderr del padre
stdio: 'pipe',
// Utilizza la codifica utf8 per i pipe stdio
encoding: 'utf8',
})
console.log(stdout)
} catch (err) {
if (err.code) {
// La generazione del processo figlio non è riuscita
console.error(err.code)
} else {
// Il figlio è stato generato ma è terminato 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'], {
// Acquisisce stdout e stderr dal processo figlio. Sovrascrive il
// comportamento predefinito di invio in streaming dell'stderr del figlio all'stderr del padre
stdio: 'pipe',
// Utilizza la codifica utf8 per i pipe stdio
encoding: 'utf8',
})
console.log(stdout)
} catch (err) {
if (err.code) {
// La generazione del processo figlio non è riuscita
console.error(err.code)
} else {
// Il figlio è stato generato ma è terminato 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 un 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
<string> Il comando da eseguire.options
<Object>cwd
<string> | <URL> Directory di lavoro corrente del processo figlio.input
<string> | <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
<string> | <Array> Configurazione stdio del figlio. Vederechild_process.spawn()
'sstdio
.stderr
per impostazione predefinita verrà inviato all'errore standard del processo padre, a meno chestdio
non sia specificato. Predefinito:'pipe'
.env
<Object> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.shell
<string> Shell con cui eseguire il comando. Vedere Requisiti shell e Shell predefinita di Windows. Predefinito:'/bin/sh'
su Unix,process.env.ComSpec
su Windows.uid
<number> Imposta l'identità utente del processo. (Vederesetuid(2)
).gid
<number> Imposta l'identità di gruppo del processo. (Vederesetgid(2)
).timeout
<number> In millisecondi, l'intervallo di tempo massimo durante il quale è consentito l'esecuzione del processo. Predefinito:undefined
.killSignal
<string> | <integer> Il valore del segnale da utilizzare quando il processo generato verrà terminato. Predefinito:'SIGTERM'
.maxBuffer
<number> 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
<string> La codifica utilizzata per tutti gli input e gli output di stdio. Predefinito:'buffer'
.windowsHide
<boolean> 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à alcun valore finché il processo figlio non si sarà completamente chiuso. Quando si verifica un timeout e viene inviato killSignal
, il metodo non restituirà un valore finché il processo non sarà completamente uscito. Se il processo figlio intercetta e gestisce il segnale SIGTERM
e non esce, il processo padre attenderà fino a quando il processo figlio non sarà uscito.
Se il processo va in timeout o ha un codice di uscita diverso da zero, questo metodo genererà un'eccezione. L'oggetto Error
conterrà l'intero risultato di 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 arbitraria di comandi.
child_process.spawnSync(command[, args][, options])
[Cronologia]
Versione | Modifiche |
---|---|
v16.4.0, v14.18.0 | L'opzione cwd può essere un oggetto WHATWG URL usando 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
<string> Il comando da eseguire.args
<string[]> Elenco di argomenti stringa.options
<Object>cwd
<string> | <URL> Directory di lavoro corrente del processo figlio.input
<string> | <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
<string> Imposta esplicitamente il valore diargv[0]
inviato al processo figlio. Questo sarà impostato sucommand
se non specificato.stdio
<string> | <Array> Configurazione stdio del figlio. Vedichild_process.spawn()
'sstdio
. Predefinito:'pipe'
.env
<Object> Coppie chiave-valore dell'ambiente. Predefinito:process.env
.uid
<number> Imposta l'identità dell'utente del processo (vedisetuid(2)
).gid
<number> Imposta l'identità del gruppo del processo (vedisetgid(2)
).timeout
<number> In millisecondi, la quantità massima di tempo consentita per l'esecuzione del processo. Predefinito:undefined
.killSignal
<string> | <integer> Il valore del segnale da utilizzare quando il processo generato verrà terminato. Predefinito:'SIGTERM'
.maxBuffer
<number> La quantità massima di dati in byte consentita su stdout o stderr. Se superato, il processo figlio viene terminato e l'output viene troncato. Vedi l'avvertenza inmaxBuffer
e Unicode. Predefinito:1024 * 1024
.encoding
<string> La codifica utilizzata per tutti gli input e output stdio. Predefinito:'buffer'
.shell
<boolean> | <string> 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).windowsVerbatimArguments
<boolean> Nessuna citazione o escape degli argomenti viene eseguita su Windows. Ignorato su Unix. Questo è impostato automaticamente sutrue
quandoshell
è specificato ed è CMD. Predefinito:false
.windowsHide
<boolean> Nasconde la finestra della console del sottoprocesso che verrebbe normalmente creata sui sistemi Windows. Predefinito:false
.
Restituisce: <Object>
pid
<number> Pid del processo figlio.output
<Array> Array di risultati dall'output stdio.stdout
<Buffer> | <string> I contenuti dioutput[1]
.stderr
<Buffer> | <string> I contenuti dioutput[2]
.status
<number> | <null> Il codice di uscita del sottoprocesso, onull
se il sottoprocesso è terminato a causa di un segnale.signal
<string> | <null> Il segnale utilizzato per terminare il sottoprocesso, onull
se il sottoprocesso non è terminato a causa di un segnale.error
<Error> L'oggetto 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à fino a quando il processo non sarà completamente uscito. 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 sanificato a questa funzione. Qualsiasi input contenente metacaratteri della shell può essere utilizzato per attivare l'esecuzione di comandi arbitrari.
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, usa 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 il processo figlio è stato terminato.
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, o 'error'
se il processo figlio non è riuscito ad avviarsi.
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 chiude tutti gli stdio con codice ${code}`)
})
ls.on('exit', code => {
console.log(`child process è uscito con codice ${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 chiude tutti gli stdio con codice ${code}`)
})
ls.on('exit', code => {
console.log(`child process è uscito con codice ${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ò o non può essere attivato 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.
Vedi anche subprocess.kill()
e subprocess.send()
.
Evento: 'exit'
Aggiunto in: v0.1.90
code
<number> Il codice di uscita se il processo figlio è terminato da solo.signal
<string> Il segnale con cui è stato terminato il processo figlio.
L'evento 'exit'
viene emesso dopo che il processo figlio termina. 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 l'evento 'exit'
viene attivato, i flussi stdio del processo figlio potrebbero essere ancora aperti.
Node.js stabilisce i 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.
Vedi 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 quando si genera il 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 con successo, l'evento 'spawn'
non viene emesso e viene invece emesso l'evento 'error'
.
Se emesso, l'evento 'spawn'
arriva prima di tutti gli altri eventi e prima che vengano ricevuti dati 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 con successo, 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 nativi C++. |
v7.1.0 | Aggiunto in: v7.1.0 |
- <Object> Un pipe che rappresenta il canale IPC verso il processo figlio.
La proprietà subprocess.channel
è un riferimento al canale IPC del figlio. Se non esiste un canale IPC, questa proprietà è undefined
.
subprocess.channel.ref()
Aggiunto in: v7.1.0
Questo metodo fa in modo 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 in modo che il canale IPC non mantenga in esecuzione il ciclo di eventi del processo padre e gli permette di terminare anche mentre il canale è aperto.
subprocess.connected
Aggiunto in: v0.7.2
- <boolean> Impostato su
false
dopo che viene 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 i processi padre e figlio, consentendo al processo figlio di terminare in modo corretto una volta che non ci sono altre connessioni che lo mantengono attivo. Dopo aver chiamato questo metodo, le proprietà subprocess.connected
e process.connected
nei processi padre e figlio (rispettivamente) saranno impostate su false
e non sarà più possibile scambiare messaggi tra i processi.
L'evento 'disconnect'
verrà emesso quando non ci sono messaggi in fase di ricezione. Ciò verrà molto spesso attivato immediatamente dopo aver chiamato subprocess.disconnect()
.
Quando il processo figlio è un'istanza di Node.js (ad es. generata utilizzando 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 successo e false
in caso contrario.
const { spawn } = require('node:child_process')
const grep = spawn('grep', ['ssh'])
grep.on('close', (code, signal) => {
console.log(`il processo figlio è terminato a causa della ricezione del segnale ${signal}`)
})
// Invia SIGHUP al processo.
grep.kill('SIGHUP')
import { spawn } from 'node:child_process'
const grep = spawn('grep', ['ssh'])
grep.on('close', (code, signal) => {
console.log(`il processo figlio è terminato a causa della ricezione del segnale ${signal}`)
})
// Invia SIGHUP al processo.
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. Nello specifico, se l'identificatore di processo (PID) è stato riassegnato a un altro processo, il segnale verrà recapitato a quel processo invece, 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 non esistono segnali POSIX, l'argomento signal
verrà ignorato ad eccezione di 'SIGKILL'
, 'SIGTERM'
, 'SIGINT'
e 'SIGQUIT'
, e il processo verrà sempre terminato con la 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 genitore. È 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() // Non termina il processo Node.js nella 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() // Non termina il processo Node.js nella 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'identificatore di processo (PID) del processo figlio. Se il processo figlio non riesce a generare a causa di errori, allora il valore è undefined
e viene emesso un error
.
const { spawn } = require('node:child_process')
const grep = spawn('grep', ['ssh'])
console.log(`PID del processo figlio generato: ${grep.pid}`)
grep.stdin.end()
import { spawn } from 'node:child_process'
const grep = spawn('grep', ['ssh'])
console.log(`PID del processo 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 rimossi per il processo figlio, forzando il processo padre ad attendere l'uscita del processo figlio prima di terminare esso stesso.
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 sono ora supportati. |
v5.0.0 | Questo metodo restituisce ora 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
. Quando ètrue
, 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()
), è possibile utilizzare il metodo subprocess.send()
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 viene sottoposto a serializzazione e 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('PADRE ha ricevuto il messaggio:', message)
})
// Fa sì che il figlio stampi: FIGLIO ha ricevuto il messaggio: { hello: 'mondo' }
forkedProcess.send({ hello: 'mondo' })
import { fork } from 'node:child_process'
const forkedProcess = fork(`${import.meta.dirname}/sub.js`)
forkedProcess.on('message', message => {
console.log('PADRE ha ricevuto il messaggio:', message)
})
// Fa sì che il figlio stampi: FIGLIO ha ricevuto il messaggio: { hello: 'mondo' }
forkedProcess.send({ hello: 'mondo' })
E quindi lo script figlio, 'sub.js'
, potrebbe essere simile a questo:
process.on('message', message => {
console.log('FIGLIO ha ricevuto il messaggio:', message)
})
// Fa sì che il padre stampi: PADRE ha ricevuto il messaggio: { foo: 'bar', baz: null }
process.send({ foo: 'bar', baz: NaN })
I processi Node.js figlio avranno un proprio metodo process.send()
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 all'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 eventi 'internalMessage'
in quanto sono soggetti a modifiche senza preavviso.
L'argomento facoltativo 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
facoltativa è 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 o 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
. Ciò può accadere, ad esempio, quando il processo figlio è già terminato.
subprocess.send()
restituirà false
se il canale si è chiuso o quando il backlog di messaggi non inviati supera una soglia che rende inopportuno inviarne altri. In caso contrario, 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 parent')
})
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 parent')
})
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 child')
})
}
})
Una volta che il server è ora condiviso tra il parent e il child, alcune connessioni possono essere gestite dal parent e alcune dal child.
Mentre l'esempio sopra utilizza un server creato utilizzando il modulo node:net
, i server del modulo node:dgram
utilizzano esattamente lo stesso flusso di lavoro con l'eccezione di ascoltare un evento 'message'
invece di 'connection'
e utilizzare 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 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 child. 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 è priorità speciale...
if (socket.remoteAddress === '74.125.127.100') {
special.send('socket', socket)
return
}
// Questa è 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 child. 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 è priorità speciale...
if (socket.remoteAddress === '74.125.127.100') {
special.send('socket', socket)
return
}
// Questa è 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 utilizzare .maxConnections
su un socket che è stato passato a un subprocesso. Il parent non può tenere traccia di quando il socket viene distrutto.
Qualsiasi gestore 'message'
nel subprocesso dovrebbe 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
Uno Stream leggibile
che rappresenta l'stderr
del processo figlio.
Se il processo figlio è stato generato con stdio[2]
impostato su un valore 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 avviato correttamente.
subprocess.stdin
Aggiunto in: v0.1.90
Uno Stream Writable
che rappresenta lo stdin
del processo figlio.
Se un processo figlio aspetta di leggere tutto il suo input, il processo figlio non continuerà finché questo stream non è stato chiuso tramite end()
.
Se il processo figlio è stato generato con stdio[0]
impostato su un valore 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 verso il processo figlio, corrispondente alle posizioni nell'opzione stdio
passata a child_process.spawn()
che sono state impostate al 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 l'fd 1
del figlio (stdout) è configurato come pipe, quindi solo 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 lo stdin del genitore per il figlio.
'pipe', // Invia lo stdout del figlio al genitore tramite pipe.
fs.openSync('err.out', 'w'), // Invia lo 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 lo stdin del genitore per il figlio.
'pipe', // Invia lo stdout del figlio al genitore tramite pipe.
fs.openSync('err.out', 'w'), // Invia lo 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
Un Readable Stream
che rappresenta lo stdout
del processo figlio.
Se il processo figlio è stato generato con stdio[1]
impostato su qualcosa di diverso da 'pipe'
, allora questo sarà null
.
subprocess.stdout
è un alias per subprocess.stdio[1]
. Entrambe le proprietà si riferiranno allo stesso valore.
const { spawn } = require('node:child_process')
const subprocess = spawn('ls')
subprocess.stdout.on('data', data => {
console.log(`Ricevuto blocco ${data}`)
})
import { spawn } from 'node:child_process'
const subprocess = spawn('ls')
subprocess.stdout.on('data', data => {
console.log(`Ricevuto blocco ${data}`)
})
La proprietà subprocess.stdout
può essere null
o undefined
se il processo figlio non è stato generato con successo.
subprocess.unref()
Aggiunto in: v0.7.10
Per impostazione predefinita, il processo principale attenderà l'uscita del processo figlio scollegato. Per impedire che il processo principale attenda l'uscita di un dato subprocess
, utilizzare il metodo subprocess.unref()
. Ciò farà sì che il ciclo di eventi del genitore non includa il processo figlio nel suo conteggio dei riferimenti, consentendo al genitore di uscire indipendentemente dal figlio, a meno che non ci sia un canale IPC stabilito tra il figlio e il processo genitore.
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 UTF-8 a stdout
anche se ci sono solo 4 caratteri.
Requisiti della shell
La shell dovrebbe capire lo switch -c
. Se la shell è 'cmd.exe'
, dovrebbe capire gli switch /d /s /c
e l'analisi della riga di comando dovrebbe essere compatibile.
Shell predefinita di Windows
Sebbene Microsoft specifichi che %COMSPEC%
debba contenere il percorso di 'cmd.exe'
nell'ambiente root, i processi figlio non sono sempre soggetti allo stesso requisito. Pertanto, nelle funzioni child_process
in cui è possibile generare una shell, 'cmd.exe'
viene utilizzato 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 trasmesse attraverso la fase 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()
.