Processo Filho
[Estável: 2 - Estável]
Estável: 2 Estabilidade: 2 - Estável
Código Fonte: lib/child_process.js
O módulo node:child_process
fornece a capacidade de gerar subprocessos de uma maneira semelhante, mas não idêntica, ao popen(3)
. Essa capacidade é fornecida principalmente pela função 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}`)
})
Por padrão, os pipes para stdin
, stdout
e stderr
são estabelecidos entre o processo Node.js pai e o subprocesso gerado. Esses pipes têm capacidade limitada (e específica da plataforma). Se o subprocesso gravar em stdout em excesso desse limite sem que a saída seja capturada, o subprocesso bloqueia aguardando que o buffer do pipe aceite mais dados. Isso é idêntico ao comportamento de pipes no shell. Use a opção { stdio: 'ignore' }
se a saída não for consumida.
A pesquisa de comandos é realizada usando a variável de ambiente options.env.PATH
se env
estiver no objeto options
. Caso contrário, process.env.PATH
é usado. Se options.env
for definido sem PATH
, a pesquisa no Unix é realizada em um caminho de pesquisa padrão de /usr/bin:/bin
(consulte o manual do seu sistema operacional para execvpe/execvp), no Windows a variável de ambiente PATH
dos processos atuais é usada.
No Windows, as variáveis de ambiente não diferenciam maiúsculas de minúsculas. O Node.js classifica lexicograficamente as chaves env
e usa a primeira que corresponde sem diferenciar maiúsculas de minúsculas. Apenas a primeira entrada (em ordem lexicográfica) será passada para o subprocesso. Isso pode levar a problemas no Windows ao passar objetos para a opção env
que tenham várias variantes da mesma chave, como PATH
e Path
.
O método child_process.spawn()
gera o processo filho de forma assíncrona, sem bloquear o loop de eventos do Node.js. A função child_process.spawnSync()
fornece funcionalidade equivalente de forma síncrona que bloqueia o loop de eventos até que o processo gerado seja encerrado ou finalizado.
Para conveniência, o módulo node:child_process
fornece algumas alternativas síncronas e assíncronas para child_process.spawn()
e child_process.spawnSync()
. Cada uma dessas alternativas é implementada em cima de child_process.spawn()
ou child_process.spawnSync()
.
child_process.exec()
: gera um shell e executa um comando nesse shell, passando ostdout
estderr
para uma função de retorno de chamada quando concluído.child_process.execFile()
: semelhante achild_process.exec()
, exceto que ele gera o comando diretamente sem primeiro gerar um shell por padrão.child_process.fork()
: gera um novo processo Node.js e invoca um módulo especificado com um canal de comunicação IPC estabelecido que permite o envio de mensagens entre pai e filho.child_process.execSync()
: uma versão síncrona dechild_process.exec()
que bloqueará o loop de eventos do Node.js.child_process.execFileSync()
: uma versão síncrona dechild_process.execFile()
que bloqueará o loop de eventos do Node.js.
Para certos casos de uso, como automatizar scripts de shell, as contrapartes síncronas podem ser mais convenientes. Em muitos casos, no entanto, os métodos síncronos podem ter um impacto significativo no desempenho devido ao atraso do loop de eventos enquanto os processos gerados são concluídos.
Criação de processos assíncronos
Os métodos child_process.spawn()
, child_process.fork()
, child_process.exec()
e child_process.execFile()
seguem o padrão de programação assíncrona idiomático típico de outras APIs do Node.js.
Cada um dos métodos retorna uma instância de ChildProcess
. Esses objetos implementam a API EventEmitter
do Node.js, permitindo que o processo pai registre funções de ouvinte que são chamadas quando certos eventos ocorrem durante o ciclo de vida do processo filho.
Os métodos child_process.exec()
e child_process.execFile()
também permitem que uma função callback
opcional seja especificada e invocada quando o processo filho é encerrado.
Gerando arquivos .bat
e .cmd
no Windows
A importância da distinção entre child_process.exec()
e child_process.execFile()
pode variar com base na plataforma. Em sistemas operacionais do tipo Unix (Unix, Linux, macOS), o child_process.execFile()
pode ser mais eficiente porque não gera um shell por padrão. No Windows, no entanto, arquivos .bat
e .cmd
não são executáveis por conta própria sem um terminal e, portanto, não podem ser iniciados usando child_process.execFile()
. Ao executar no Windows, arquivos .bat
e .cmd
podem ser invocados usando child_process.spawn()
com a opção shell
definida, com child_process.exec()
, ou gerando cmd.exe
e passando o arquivo .bat
ou .cmd
como um argumento (que é o que a opção shell
e child_process.exec()
fazem). Em qualquer caso, se o nome do arquivo de script contiver espaços, ele precisará ser citado.
// OU...
const { exec, spawn } = require('node:child_process')
exec('my.bat', (err, stdout, stderr) => {
if (err) {
console.error(err)
return
}
console.log(stdout)
})
// Script com espaços no nome do arquivo:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true })
// ou:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
// ...
})
// OU...
import { exec, spawn } from 'node:child_process'
exec('my.bat', (err, stdout, stderr) => {
if (err) {
console.error(err)
return
}
console.log(stdout)
})
// Script com espaços no nome do arquivo:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true })
// ou:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
// ...
})
child_process.exec(command[, options][, callback])
[Histórico]
Versão | Mudanças |
---|---|
v15.4.0 | Adicionado suporte para AbortSignal. |
v16.4.0, v14.18.0 | A opção cwd pode ser um objeto WHATWG URL usando o protocolo file: . |
v8.8.0 | A opção windowsHide agora é suportada. |
v0.1.90 | Adicionado em: v0.1.90 |
command
<string> O comando a ser executado, com argumentos separados por espaço.options
<Object>cwd
<string> | <URL> Diretório de trabalho atual do processo filho. Padrão:process.cwd()
.env
<Object> Pares de chave-valor de ambiente. Padrão:process.env
.encoding
<string> Padrão:'utf8'
shell
<string> Shell para executar o comando. Veja Requisitos de Shell e Shell padrão do Windows. Padrão:'/bin/sh'
no Unix,process.env.ComSpec
no Windows.signal
<AbortSignal> permite abortar o processo filho usando um AbortSignal.timeout
<number> Padrão:0
maxBuffer
<number> Maior quantidade de dados em bytes permitida em stdout ou stderr. Se excedido, o processo filho é encerrado e qualquer saída é truncada. Veja a ressalva emmaxBuffer
e Unicode. Padrão:1024 * 1024
.killSignal
<string> | <integer> Padrão:'SIGTERM'
uid
<number> Define a identidade do usuário do processo (vejasetuid(2)
).gid
<number> Define a identidade do grupo do processo (vejasetgid(2)
).windowsHide
<boolean> Oculta a janela do console do subprocesso que normalmente seria criada em sistemas Windows. Padrão:false
.
callback
<Function> chamada com a saída quando o processo termina.Retorna: <ChildProcess>
Gera um shell e, em seguida, executa o command
dentro desse shell, armazenando em buffer qualquer saída gerada. A string command
passada para a função exec é processada diretamente pelo shell e caracteres especiais (variam com base no shell) precisam ser tratados de acordo:
const { exec } = require('node:child_process')
exec('"/caminho/para/arquivo de teste/teste.sh" arg1 arg2')
// Aspas duplas são usadas para que o espaço no caminho não seja interpretado como
// um delimitador de múltiplos argumentos.
exec('echo "A variável \\$HOME é $HOME"')
// A variável $HOME é escapada na primeira instância, mas não na segunda.
import { exec } from 'node:child_process'
exec('"/caminho/para/arquivo de teste/teste.sh" arg1 arg2')
// As aspas duplas são usadas para que o espaço no caminho não seja interpretado como
// um delimitador de múltiplos argumentos.
exec('echo "A variável \\$HOME é $HOME"')
// A variável $HOME é escapada na primeira instância, mas não na segunda.
Nunca passe dados de entrada de usuário não higienizados para esta função. Qualquer entrada contendo metacaracteres de shell pode ser usada para acionar a execução arbitrária de comandos.
Se uma função callback
for fornecida, ela será chamada com os argumentos (error, stdout, stderr)
. Em caso de sucesso, error
será null
. Em caso de erro, error
será uma instância de Error
. A propriedade error.code
será o código de saída do processo. Por convenção, qualquer código de saída diferente de 0
indica um erro. error.signal
será o sinal que encerrou o processo.
Os argumentos stdout
e stderr
passados para o callback conterão a saída stdout e stderr do processo filho. Por padrão, o Node.js irá decodificar a saída como UTF-8 e passar strings para o callback. A opção encoding
pode ser usada para especificar a codificação de caracteres usada para decodificar a saída stdout e stderr. Se encoding
for 'buffer'
, ou uma codificação de caracteres não reconhecida, objetos Buffer
serão passados para o callback.
const { exec } = require('node:child_process')
exec('cat *.js arquivo_faltando | wc -l', (error, stdout, stderr) => {
if (error) {
console.error(`erro de execução: ${error}`)
return
}
console.log(`stdout: ${stdout}`)
console.error(`stderr: ${stderr}`)
})
import { exec } from 'node:child_process'
exec('cat *.js arquivo_faltando | wc -l', (error, stdout, stderr) => {
if (error) {
console.error(`erro de execução: ${error}`)
return
}
console.log(`stdout: ${stdout}`)
console.error(`stderr: ${stderr}`)
})
Se timeout
for maior que 0
, o processo pai enviará o sinal identificado pela propriedade killSignal
(o padrão é 'SIGTERM'
) se o processo filho for executado por mais de timeout
milissegundos.
Ao contrário da chamada do sistema POSIX exec(3)
, child_process.exec()
não substitui o processo existente e usa um shell para executar o comando.
Se este método for invocado como sua versão util.promisify()
ed, ele retornará uma Promise
para um Object
com as propriedades stdout
e stderr
. A instância ChildProcess
retornada é anexada à Promise
como uma propriedade child
. Em caso de erro (incluindo qualquer erro resultante em um código de saída diferente de 0), uma promessa rejeitada é retornada, com o mesmo objeto error
fornecido no callback, mas com duas propriedades adicionais stdout
e stderr
.
const util = require('node:util')
const exec = util.promisify(require('node:child_process').exec)
async function exemploLs() {
const { stdout, stderr } = await exec('ls')
console.log('stdout:', stdout)
console.error('stderr:', stderr)
}
exemploLs()
import { promisify } from 'node:util'
import child_process from 'node:child_process'
const exec = promisify(child_process.exec)
async function exemploLs() {
const { stdout, stderr } = await exec('ls')
console.log('stdout:', stdout)
console.error('stderr:', stderr)
}
exemploLs()
Se a opção signal
estiver habilitada, chamar .abort()
no AbortController
correspondente é semelhante a chamar .kill()
no processo filho, exceto que o erro passado para o callback será um AbortError
:
const { exec } = require('node:child_process')
const controller = new AbortController()
const { signal } = controller
const child = exec('grep ssh', { signal }, error => {
console.error(error) // um 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) // um AbortError
})
controller.abort()
child_process.execFile(file[, args][, options][, callback])
[Histórico]
Versão | Mudanças |
---|---|
v16.4.0, v14.18.0 | A opção cwd pode ser um objeto WHATWG URL usando o protocolo file: . |
v15.4.0, v14.17.0 | Foi adicionado suporte para AbortSignal. |
v8.8.0 | A opção windowsHide agora é suportada. |
v0.1.91 | Adicionado em: v0.1.91 |
file
<string> O nome ou caminho do arquivo executável a ser executado.args
<string[]> Lista de argumentos de string.options
<Object>cwd
<string> | <URL> Diretório de trabalho atual do processo filho.env
<Object> Pares chave-valor do ambiente. Padrão:process.env
.encoding
<string> Padrão:'utf8'
timeout
<number> Padrão:0
maxBuffer
<number> Maior quantidade de dados em bytes permitida em stdout ou stderr. Se excedido, o processo filho é terminado e qualquer saída é truncada. Veja a ressalva emmaxBuffer
e Unicode. Padrão:1024 * 1024
.killSignal
<string> | <integer> Padrão:'SIGTERM'
uid
<number> Define a identidade do usuário do processo (vejasetuid(2)
).gid
<number> Define a identidade do grupo do processo (vejasetgid(2)
).windowsHide
<boolean> Oculta a janela do console do subprocesso que normalmente seria criada em sistemas Windows. Padrão:false
.windowsVerbatimArguments
<boolean> Nenhuma citação ou escape de argumentos é feito no Windows. Ignorado no Unix. Padrão:false
.shell
<boolean> | <string> Setrue
, executacommand
dentro de um shell. Usa'/bin/sh'
no Unix eprocess.env.ComSpec
no Windows. Um shell diferente pode ser especificado como uma string. Veja Requisitos do shell e Shell padrão do Windows. Padrão:false
(sem shell).signal
<AbortSignal> permite abortar o processo filho usando um AbortSignal.
callback
<Function> Chamado com a saída quando o processo termina.Retorna: <ChildProcess>
A função child_process.execFile()
é semelhante a child_process.exec()
, exceto que ela não gera um shell por padrão. Em vez disso, o arquivo executável especificado file
é gerado diretamente como um novo processo, tornando-o um pouco mais eficiente do que child_process.exec()
.
As mesmas opções de child_process.exec()
são suportadas. Como um shell não é gerado, comportamentos como redirecionamento de E/S e globbing de arquivos não são suportados.
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)
})
Os argumentos stdout
e stderr
passados para o callback conterão a saída stdout e stderr do processo filho. Por padrão, o Node.js decodificará a saída como UTF-8 e passará strings para o callback. A opção encoding
pode ser usada para especificar a codificação de caracteres usada para decodificar a saída stdout e stderr. Se encoding
for 'buffer'
ou uma codificação de caracteres não reconhecida, objetos Buffer
serão passados para o callback.
Se este método for invocado como sua versão util.promisify()
, ele retornará uma Promise
para um Object
com propriedades stdout
e stderr
. A instância ChildProcess
retornada é anexada à Promise
como uma propriedade child
. Em caso de erro (incluindo qualquer erro que resulte em um código de saída diferente de 0), uma promise rejeitada é retornada, com o mesmo objeto error
fornecido no callback, mas com duas propriedades adicionais 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 a opção shell
estiver habilitada, não passe entradas de usuário não higienizadas para esta função. Qualquer entrada que contenha metacaracteres de shell pode ser usada para acionar a execução arbitrária de comandos.
Se a opção signal
estiver habilitada, chamar .abort()
no AbortController
correspondente é semelhante a chamar .kill()
no processo filho, exceto que o erro passado para o callback será um AbortError
:
const { execFile } = require('node:child_process')
const controller = new AbortController()
const { signal } = controller
const child = execFile('node', ['--version'], { signal }, error => {
console.error(error) // um 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) // um AbortError
})
controller.abort()
child_process.fork(modulePath[, args][, options])
[Histórico]
Versão | Mudanças |
---|---|
v17.4.0, v16.14.0 | O parâmetro modulePath pode ser um objeto URL WHATWG usando o protocolo file: . |
v16.4.0, v14.18.0 | A opção cwd pode ser um objeto URL WHATWG usando o protocolo file: . |
v15.13.0, v14.18.0 | O timeout foi adicionado. |
v15.11.0, v14.18.0 | killSignal para AbortSignal foi adicionado. |
v15.6.0, v14.17.0 | O suporte a AbortSignal foi adicionado. |
v13.2.0, v12.16.0 | A opção serialization agora é suportada. |
v8.0.0 | A opção stdio agora pode ser uma string. |
v6.4.0 | A opção stdio agora é suportada. |
v0.5.0 | Adicionado em: v0.5.0 |
modulePath
<string> | <URL> O módulo a ser executado no filho.args
<string[]> Lista de argumentos de string.options
<Object>cwd
<string> | <URL> Diretório de trabalho atual do processo filho.detached
<boolean> Prepare o processo filho para ser executado independentemente de seu processo pai. O comportamento específico depende da plataforma, consulteoptions.detached
).env
<Object> Pares de chave-valor de ambiente. Padrão:process.env
.execPath
<string> Executável usado para criar o processo filho.execArgv
<string[]> Lista de argumentos de string passados para o executável. Padrão:process.execArgv
.gid
<number> Define a identidade do grupo do processo (consultesetgid(2)
).serialization
<string> Especifica o tipo de serialização usado para enviar mensagens entre processos. Os valores possíveis são'json'
e'advanced'
. Consulte Serialização avançada para obter mais detalhes. Padrão:'json'
.signal
<AbortSignal> Permite fechar o processo filho usando um AbortSignal.killSignal
<string> | <integer> O valor do sinal a ser usado quando o processo gerado for finalizado por timeout ou sinal de aborto. Padrão:'SIGTERM'
.silent
<boolean> Setrue
, stdin, stdout e stderr do processo filho serão direcionados para o processo pai, caso contrário, eles serão herdados do processo pai, consulte as opções'pipe'
e'inherit'
parachild_process.spawn()
'sstdio
para obter mais detalhes. Padrão:false
.stdio
<Array> | <string> Consultechild_process.spawn()
'sstdio
. Quando esta opção é fornecida, ela substituisilent
. Se a variante de array for usada, ela deve conter exatamente um item com o valor'ipc'
ou um erro será lançado. Por exemplo[0, 1, 2, 'ipc']
.uid
<number> Define a identidade do usuário do processo (consultesetuid(2)
).windowsVerbatimArguments
<boolean> Nenhuma citação ou escape de argumentos é feito no Windows. Ignorado no Unix. Padrão:false
.timeout
<number> Em milissegundos, o tempo máximo que o processo tem permissão para ser executado. Padrão:undefined
.
- Retorna: <ChildProcess>
O método child_process.fork()
é um caso especial de child_process.spawn()
usado especificamente para gerar novos processos do Node.js. Como child_process.spawn()
, um objeto ChildProcess
é retornado. O ChildProcess
retornado terá um canal de comunicação adicional integrado que permite que as mensagens sejam passadas de um lado para o outro entre o pai e o filho. Consulte subprocess.send()
para obter detalhes.
Tenha em mente que os processos filhos do Node.js gerados são independentes do pai, com exceção do canal de comunicação IPC que é estabelecido entre os dois. Cada processo tem sua própria memória, com suas próprias instâncias do V8. Devido às alocações de recursos adicionais necessárias, não é recomendado gerar um grande número de processos filhos do Node.js.
Por padrão, child_process.fork()
gerará novas instâncias do Node.js usando o process.execPath
do processo pai. A propriedade execPath
no objeto options
permite que um caminho de execução alternativo seja usado.
Os processos do Node.js iniciados com um execPath
personalizado se comunicarão com o processo pai usando o descritor de arquivo (fd) identificado usando a variável de ambiente NODE_CHANNEL_FD
no processo filho.
Ao contrário da chamada do sistema POSIX fork(2)
, child_process.fork()
não clona o processo atual.
A opção shell
disponível em child_process.spawn()
não é suportada por child_process.fork()
e será ignorada se definida.
Se a opção signal
estiver habilitada, chamar .abort()
no AbortController
correspondente é semelhante a chamar .kill()
no processo filho, exceto que o erro passado para o callback será um AbortError
:
const { fork } = require('node:child_process')
const process = require('node:process')
if (process.argv[2] === 'child') {
setTimeout(() => {
console.log(`Olá de ${process.argv[2]}!`)
}, 1_000)
} else {
const controller = new AbortController()
const { signal } = controller
const child = fork(__filename, ['child'], { signal })
child.on('error', err => {
// Isso será chamado com err sendo um AbortError se o controlador abortar
})
controller.abort() // Para o processo filho
}
import { fork } from 'node:child_process'
import process from 'node:process'
if (process.argv[2] === 'child') {
setTimeout(() => {
console.log(`Olá de ${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 => {
// Isso será chamado com err sendo um AbortError se o controlador abortar
})
controller.abort() // Para o processo filho
}
child_process.spawn(command[, args][, options])
[Histórico]
Versão | Mudanças |
---|---|
v16.4.0, v14.18.0 | A opção cwd pode ser um objeto URL WHATWG usando o protocolo file: . |
v15.13.0, v14.18.0 | O tempo limite foi adicionado. |
v15.11.0, v14.18.0 | killSignal para AbortSignal foi adicionado. |
v15.5.0, v14.17.0 | Suporte para AbortSignal foi adicionado. |
v13.2.0, v12.16.0 | A opção serialization agora é suportada. |
v8.8.0 | A opção windowsHide agora é suportada. |
v6.4.0 | A opção argv0 agora é suportada. |
v5.7.0 | A opção shell agora é suportada. |
v0.1.90 | Adicionado em: v0.1.90 |
command
<string> O comando a ser executado.args
<string[]> Lista de argumentos de string.options
<Object>cwd
<string> | <URL> Diretório de trabalho atual do processo filho.env
<Object> Pares de chave-valor de ambiente. Padrão:process.env
.argv0
<string> Define explicitamente o valor deargv[0]
enviado para o processo filho. Isso será definido comocommand
se não for especificado.stdio
<Array> | <string> Configuração do stdio do filho (consulteoptions.stdio
).detached
<boolean> Prepara o processo filho para ser executado independentemente de seu processo pai. O comportamento específico depende da plataforma, consulteoptions.detached
).uid
<number> Define a identidade do usuário do processo (consultesetuid(2)
).gid
<number> Define a identidade do grupo do processo (consultesetgid(2)
).serialization
<string> Especifica o tipo de serialização usado para enviar mensagens entre processos. Os valores possíveis são'json'
e'advanced'
. Consulte Serialização avançada para obter mais detalhes. Padrão:'json'
.shell
<boolean> | <string> Setrue
, executacommand
dentro de um shell. Usa'/bin/sh'
no Unix eprocess.env.ComSpec
no Windows. Um shell diferente pode ser especificado como uma string. Consulte Requisitos do shell e Shell padrão do Windows. Padrão:false
(sem shell).windowsVerbatimArguments
<boolean> Nenhuma citação ou escape de argumentos é feito no Windows. Ignorado no Unix. Isso é definido comotrue
automaticamente quandoshell
é especificado e é CMD. Padrão:false
.windowsHide
<boolean> Oculta a janela do console do subprocesso que normalmente seria criada em sistemas Windows. Padrão:false
.signal
<AbortSignal> permite abortar o processo filho usando um AbortSignal.timeout
<number> Em milissegundos, o tempo máximo que o processo pode ser executado. Padrão:undefined
.killSignal
<string> | <integer> O valor do sinal a ser usado quando o processo gerado for encerrado por tempo limite ou sinal de aborto. Padrão:'SIGTERM'
.
Retorna: <ChildProcess>
O método child_process.spawn()
gera um novo processo usando o command
fornecido, com argumentos de linha de comando em args
. Se omitido, args
é padronizado como um array vazio.
Se a opção shell
estiver habilitada, não passe entradas de usuário não higienizadas para esta função. Qualquer entrada que contenha metacaracteres do shell pode ser usada para acionar a execução arbitrária de comandos.
Um terceiro argumento pode ser usado para especificar opções adicionais, com esses padrões:
const defaults = {
cwd: undefined,
env: process.env,
}
Use cwd
para especificar o diretório de trabalho a partir do qual o processo é gerado. Se não for fornecido, o padrão é herdar o diretório de trabalho atual. Se fornecido, mas o caminho não existir, o processo filho emite um erro ENOENT
e sai imediatamente. ENOENT
também é emitido quando o comando não existe.
Use env
para especificar variáveis de ambiente que serão visíveis para o novo processo, o padrão é process.env
.
Valores undefined
em env
serão ignorados.
Exemplo de execução de ls -lh /usr
, capturando stdout
, stderr
e o código de saída:
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}`)
})
Exemplo: Uma maneira muito elaborada de executar 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}`)
}
})
Exemplo de verificação de spawn
falhado:
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.')
})
Certas plataformas (macOS, Linux) usarão o valor de argv[0]
para o título do processo, enquanto outras (Windows, SunOS) usarão command
.
O Node.js sobrescreve argv[0]
com process.execPath
na inicialização, portanto process.argv[0]
em um processo filho do Node.js não corresponderá ao parâmetro argv0
passado para spawn
do pai. Recupere-o com a propriedade process.argv0
.
Se a opção signal
estiver habilitada, chamar .abort()
no AbortController
correspondente é semelhante a chamar .kill()
no processo filho, exceto que o erro passado para o retorno de chamada será um AbortError
:
const { spawn } = require('node:child_process')
const controller = new AbortController()
const { signal } = controller
const grep = spawn('grep', ['ssh'], { signal })
grep.on('error', err => {
// Isso será chamado com err sendo um AbortError se o controlador abortar
})
controller.abort() // Interrompe o processo filho
import { spawn } from 'node:child_process'
const controller = new AbortController()
const { signal } = controller
const grep = spawn('grep', ['ssh'], { signal })
grep.on('error', err => {
// Isso será chamado com err sendo um AbortError se o controlador abortar
})
controller.abort() // Interrompe o processo filho
options.detached
Adicionado em: v0.7.10
No Windows, definir options.detached
como true
possibilita que o processo filho continue em execução após o encerramento do processo pai. O processo filho terá sua própria janela de console. Uma vez habilitado para um processo filho, não pode ser desabilitado.
Em plataformas não Windows, se options.detached
for definido como true
, o processo filho se tornará o líder de um novo grupo de processos e sessão. Os processos filhos podem continuar em execução após o encerramento do processo pai, independentemente de estarem ou não desconectados. Consulte setsid(2)
para mais informações.
Por padrão, o pai aguardará a saída do processo filho desconectado. Para impedir que o processo pai aguarde a saída de um determinado subprocess
, use o método subprocess.unref()
. Isso fará com que o loop de eventos do processo pai não inclua o processo filho em sua contagem de referência, permitindo que o processo pai saia independentemente do processo filho, a menos que haja um canal IPC estabelecido entre o filho e os processos pais.
Ao usar a opção detached
para iniciar um processo de longa duração, o processo não permanecerá em execução em segundo plano após a saída do pai, a menos que seja fornecida uma configuração stdio
que não esteja conectada ao pai. Se o stdio
do processo pai for herdado, o processo filho permanecerá anexado ao terminal de controle.
Exemplo de um processo de longa duração, desconectando e também ignorando seus descritores de arquivos stdio
pai, para ignorar o encerramento do pai:
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()
Alternativamente, pode-se redirecionar a saída do processo filho para arquivos:
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
[Histórico]
Versão | Alterações |
---|---|
v15.6.0, v14.18.0 | Adicionada a flag overlapped para stdio. |
v3.3.1 | O valor 0 agora é aceito como um descritor de arquivo. |
v0.7.10 | Adicionado em: v0.7.10 |
A opção options.stdio
é usada para configurar os pipes que são estabelecidos entre o processo pai e o processo filho. Por padrão, o stdin, stdout e stderr do filho são redirecionados para os fluxos subprocess.stdin
, subprocess.stdout
e subprocess.stderr
correspondentes no objeto ChildProcess
. Isso é equivalente a definir options.stdio
igual a ['pipe', 'pipe', 'pipe']
.
Por conveniência, options.stdio
pode ser uma das seguintes strings:
'pipe'
: equivalente a['pipe', 'pipe', 'pipe']
(o padrão)'overlapped'
: equivalente a['overlapped', 'overlapped', 'overlapped']
'ignore'
: equivalente a['ignore', 'ignore', 'ignore']
'inherit'
: equivalente a['inherit', 'inherit', 'inherit']
ou[0, 1, 2]
Caso contrário, o valor de options.stdio
é um array onde cada índice corresponde a um fd no filho. Os fds 0, 1 e 2 correspondem a stdin, stdout e stderr, respectivamente. Fds adicionais podem ser especificados para criar pipes adicionais entre o pai e o filho. O valor é um dos seguintes:
const { spawn } = require('node:child_process')
const process = require('node:process')
// O filho usará os stdios do pai.
spawn('prg', [], { stdio: 'inherit' })
// Gera um filho compartilhando apenas stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] })
// Abre um fd extra=4, para interagir com programas apresentando uma
// interface estilo startd.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] })
import { spawn } from 'node:child_process'
import process from 'node:process'
// O filho usará os stdios do pai.
spawn('prg', [], { stdio: 'inherit' })
// Gera um filho compartilhando apenas stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] })
// Abre um fd extra=4, para interagir com programas apresentando uma
// interface estilo startd.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] })
Vale a pena notar que, quando um canal IPC é estabelecido entre os processos pai e filho, e o processo filho é uma instância do Node.js, o processo filho é iniciado com o canal IPC não referenciado (usando unref()
) até que o processo filho registre um manipulador de eventos para o evento 'disconnect'
ou o evento 'message'
. Isso permite que o processo filho saia normalmente sem que o processo seja mantido aberto pelo canal IPC aberto. Veja também: child_process.exec()
e child_process.fork()
.
Criação de processo síncrono
Os métodos child_process.spawnSync()
, child_process.execSync()
e child_process.execFileSync()
são síncronos e bloquearão o loop de eventos do Node.js, pausando a execução de qualquer código adicional até que o processo gerado seja encerrado.
Chamadas de bloqueio como essas são mais úteis para simplificar tarefas gerais de script e para simplificar o carregamento/processamento da configuração do aplicativo na inicialização.
child_process.execFileSync(file[, args][, options])
[Histórico]
Versão | Mudanças |
---|---|
v16.4.0, v14.18.0 | A opção cwd pode ser um objeto URL WHATWG usando o protocolo file: . |
v10.10.0 | A opção input agora pode ser qualquer TypedArray ou DataView . |
v8.8.0 | A opção windowsHide agora é suportada. |
v8.0.0 | A opção input agora pode ser um Uint8Array . |
v6.2.1, v4.5.0 | A opção encoding agora pode ser explicitamente definida como buffer . |
v0.11.12 | Adicionado em: v0.11.12 |
file
<string> O nome ou caminho do arquivo executável a ser executado.args
<string[]> Lista de argumentos de string.options
<Object>cwd
<string> | <URL> Diretório de trabalho atual do processo filho.input
<string> | <Buffer> | <TypedArray> | <DataView> O valor que será passado como stdin para o processo gerado. Sestdio[0]
estiver definido como'pipe'
, fornecer este valor substituirástdio[0]
.stdio
<string> | <Array> Configuração stdio do filho. Consulte ostdio
dechild_process.spawn()
.stderr
por padrão será enviado para o stderr do processo pai, a menos questdio
seja especificado. Padrão:'pipe'
.env
<Object> Pares de chave-valor de ambiente. Padrão:process.env
.uid
<number> Define a identidade do usuário do processo (consultesetuid(2)
).gid
<number> Define a identidade do grupo do processo (consultesetgid(2)
).timeout
<number> Em milissegundos, o tempo máximo que o processo pode ser executado. Padrão:undefined
.killSignal
<string> | <integer> O valor do sinal a ser usado quando o processo gerado for encerrado. Padrão:'SIGTERM'
.maxBuffer
<number> Maior quantidade de dados em bytes permitida em stdout ou stderr. Se excedido, o processo filho é encerrado. Consulte o aviso emmaxBuffer
e Unicode. Padrão:1024 * 1024
.encoding
<string> A codificação usada para todas as entradas e saídas de stdio. Padrão:'buffer'
.windowsHide
<boolean> Oculta a janela do console do subprocesso que normalmente seria criada em sistemas Windows. Padrão:false
.shell
<boolean> | <string> Setrue
, executacommand
dentro de um shell. Usa'/bin/sh'
no Unix eprocess.env.ComSpec
no Windows. Um shell diferente pode ser especificado como uma string. Consulte Requisitos do shell e Shell padrão do Windows. Padrão:false
(sem shell).
O método child_process.execFileSync()
é geralmente idêntico a child_process.execFile()
, com a exceção de que o método não retornará até que o processo filho esteja totalmente fechado. Quando um tempo limite for encontrado e killSignal
for enviado, o método não retornará até que o processo seja totalmente encerrado.
Se o processo filho interceptar e tratar o sinal SIGTERM
e não for encerrado, o processo pai ainda esperará até que o processo filho seja encerrado.
Se o processo atingir o tempo limite ou tiver um código de saída diferente de zero, este método lançará um Error
que incluirá o resultado completo do child_process.spawnSync()
subjacente.
Se a opção shell
estiver habilitada, não passe dados de entrada do usuário não sanitizados para esta função. Qualquer entrada que contenha metacaracteres de shell pode ser usada para acionar a execução arbitrária de comandos.
const { execFileSync } = require('node:child_process')
try {
const stdout = execFileSync('my-script.sh', ['my-arg'], {
// Captura stdout e stderr do processo filho. Substitui o
// comportamento padrão de transmitir o stderr do filho para o stderr do pai
stdio: 'pipe',
// Use a codificação utf8 para pipes stdio
encoding: 'utf8',
})
console.log(stdout)
} catch (err) {
if (err.code) {
// Falha ao gerar o processo filho
console.error(err.code)
} else {
// O filho foi gerado, mas saiu com código de saída diferente de zero
// O erro contém qualquer stdout e stderr do filho
const { stdout, stderr } = err
console.error({ stdout, stderr })
}
}
import { execFileSync } from 'node:child_process'
try {
const stdout = execFileSync('my-script.sh', ['my-arg'], {
// Captura stdout e stderr do processo filho. Substitui o
// comportamento padrão de transmitir o stderr do filho para o stderr do pai
stdio: 'pipe',
// Use a codificação utf8 para pipes stdio
encoding: 'utf8',
})
console.log(stdout)
} catch (err) {
if (err.code) {
// Falha ao gerar o processo filho
console.error(err.code)
} else {
// O filho foi gerado, mas saiu com código de saída diferente de zero
// O erro contém qualquer stdout e stderr do filho
const { stdout, stderr } = err
console.error({ stdout, stderr })
}
}
child_process.execSync(command[, options])
[Histórico]
Versão | Mudanças |
---|---|
v16.4.0, v14.18.0 | A opção cwd pode ser um objeto URL WHATWG usando o protocolo file: . |
v10.10.0 | A opção input agora pode ser qualquer TypedArray ou um DataView . |
v8.8.0 | A opção windowsHide agora é suportada. |
v8.0.0 | A opção input agora pode ser um Uint8Array . |
v0.11.12 | Adicionado em: v0.11.12 |
command
<string> O comando a ser executado.options
<Object>cwd
<string> | <URL> Diretório de trabalho atual do processo filho.input
<string> | <Buffer> | <TypedArray> | <DataView> O valor que será passado como stdin para o processo gerado. Sestdio[0]
estiver definido como'pipe'
, fornecer esse valor substituirástdio[0]
.stdio
<string> | <Array> Configuração stdio do filho. Vejachild_process.spawn()
'sstdio
.stderr
por padrão será direcionado para o stderr do processo pai, a menos questdio
seja especificado. Padrão:'pipe'
.env
<Object> Pares chave-valor de ambiente. Padrão:process.env
.shell
<string> Shell para executar o comando com. Veja Requisitos do Shell e Shell padrão do Windows. Padrão:'/bin/sh'
no Unix,process.env.ComSpec
no Windows.uid
<number> Define a identidade do usuário do processo. (Vejasetuid(2)
).gid
<number> Define a identidade do grupo do processo. (Vejasetgid(2)
).timeout
<number> Em milissegundos, o tempo máximo que o processo tem permissão para executar. Padrão:undefined
.killSignal
<string> | <integer> O valor do sinal a ser usado quando o processo gerado for morto. Padrão:'SIGTERM'
.maxBuffer
<number> Maior quantidade de dados em bytes permitida em stdout ou stderr. Se excedido, o processo filho é encerrado e qualquer saída é truncada. Veja a ressalva emmaxBuffer
e Unicode. Padrão:1024 * 1024
.encoding
<string> A codificação usada para todas as entradas e saídas stdio. Padrão:'buffer'
.windowsHide
<boolean> Oculta a janela do console do subprocesso que normalmente seria criada em sistemas Windows. Padrão:false
.
O método child_process.execSync()
é geralmente idêntico a child_process.exec()
com a exceção de que o método não retornará até que o processo filho tenha sido completamente fechado. Quando um tempo limite foi encontrado e killSignal
é enviado, o método não retornará até que o processo tenha sido completamente encerrado. Se o processo filho interceptar e manipular o sinal SIGTERM
e não sair, o processo pai esperará até que o processo filho tenha saído.
Se o processo expirar ou tiver um código de saída diferente de zero, este método lançará uma exceção. O objeto Error
conterá todo o resultado de child_process.spawnSync()
.
Nunca passe uma entrada de usuário não higienizada para esta função. Qualquer entrada contendo metacaracteres de shell pode ser usada para acionar a execução de comandos arbitrários.
child_process.spawnSync(command[, args][, options])
[Histórico]
Versão | Mudanças |
---|---|
v16.4.0, v14.18.0 | A opção cwd pode ser um objeto WHATWG URL usando o protocolo file: . |
v10.10.0 | A opção input agora pode ser qualquer TypedArray ou um DataView . |
v8.8.0 | A opção windowsHide agora é suportada. |
v8.0.0 | A opção input agora pode ser um Uint8Array . |
v5.7.0 | A opção shell agora é suportada. |
v6.2.1, v4.5.0 | A opção encoding agora pode ser explicitamente definida como buffer . |
v0.11.12 | Adicionado em: v0.11.12 |
command
<string> O comando a ser executado.args
<string[]> Lista de argumentos de string.options
<Object>cwd
<string> | <URL> Diretório de trabalho atual do processo filho.input
<string> | <Buffer> | <TypedArray> | <DataView> O valor que será passado como stdin para o processo gerado. Sestdio[0]
estiver definido como'pipe'
, fornecer este valor substituirástdio[0]
.argv0
<string> Define explicitamente o valor deargv[0]
enviado ao processo filho. Isso será definido comocommand
se não for especificado.stdio
<string> | <Array> Configuração stdio do filho. Vejachild_process.spawn()
'sstdio
. Padrão:'pipe'
.env
<Object> Pares de chave-valor de ambiente. Padrão:process.env
.uid
<number> Define a identidade do usuário do processo (vejasetuid(2)
).gid
<number> Define a identidade do grupo do processo (vejasetgid(2)
).timeout
<number> Em milissegundos, o tempo máximo que o processo pode ser executado. Padrão:undefined
.killSignal
<string> | <integer> O valor do sinal a ser usado quando o processo gerado será encerrado. Padrão:'SIGTERM'
.maxBuffer
<number> Maior quantidade de dados em bytes permitida em stdout ou stderr. Se excedido, o processo filho é encerrado e qualquer saída é truncada. Consulte a ressalva emmaxBuffer
e Unicode. Padrão:1024 * 1024
.encoding
<string> A codificação usada para todas as entradas e saídas stdio. Padrão:'buffer'
.shell
<boolean> | <string> Setrue
, executacommand
dentro de um shell. Usa'/bin/sh'
no Unix eprocess.env.ComSpec
no Windows. Um shell diferente pode ser especificado como uma string. Veja Requisitos do shell e Shell padrão do Windows. Padrão:false
(sem shell).windowsVerbatimArguments
<boolean> Nenhuma citação ou escape de argumentos é feita no Windows. Ignorado no Unix. Isso é definido comotrue
automaticamente quandoshell
é especificado e é CMD. Padrão:false
.windowsHide
<boolean> Oculta a janela do console do subprocesso que normalmente seria criada em sistemas Windows. Padrão:false
.
Retorna: <Object>
pid
<number> Pid do processo filho.output
<Array> Array de resultados da saída stdio.stdout
<Buffer> | <string> O conteúdo deoutput[1]
.stderr
<Buffer> | <string> O conteúdo deoutput[2]
.status
<number> | <null> O código de saída do subprocesso, ounull
se o subprocesso foi encerrado devido a um sinal.signal
<string> | <null> O sinal usado para encerrar o subprocesso, ounull
se o subprocesso não foi encerrado devido a um sinal.error
<Error> O objeto de erro se o processo filho falhou ou atingiu o tempo limite.
O método child_process.spawnSync()
é geralmente idêntico a child_process.spawn()
, com a exceção de que a função não retornará até que o processo filho tenha sido totalmente fechado. Quando um tempo limite foi encontrado e killSignal
é enviado, o método não retornará até que o processo tenha saído completamente. Se o processo interceptar e manipular o sinal SIGTERM
e não sair, o processo pai aguardará até que o processo filho tenha saído.
Se a opção shell
estiver habilitada, não passe entrada de usuário não higienizada para esta função. Qualquer entrada contendo metacaracteres de shell pode ser usada para acionar a execução arbitrária de comandos.
Classe: ChildProcess
Adicionado em: v2.2.0
- Extende: <EventEmitter>
Instâncias de ChildProcess
representam processos filhos gerados.
Não se destina que instâncias de ChildProcess
sejam criadas diretamente. Em vez disso, use os métodos child_process.spawn()
, child_process.exec()
, child_process.execFile()
ou child_process.fork()
para criar instâncias de ChildProcess
.
Evento: 'close'
Adicionado em: v0.7.7
code
<number> O código de saída se o processo filho terminou por conta própria.signal
<string> O sinal pelo qual o processo filho foi terminado.
O evento 'close'
é emitido depois que um processo terminou e os fluxos stdio de um processo filho foram fechados. Isso é diferente do evento 'exit'
, uma vez que vários processos podem compartilhar os mesmos fluxos stdio. O evento 'close'
sempre emitirá depois que 'exit'
já foi emitido, ou 'error'
se o processo filho não conseguiu ser gerado.
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(`processo filho fecha todos os stdio com o código ${code}`)
})
ls.on('exit', code => {
console.log(`processo filho finalizou com o código ${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(`processo filho fecha todos os stdio com o código ${code}`)
})
ls.on('exit', code => {
console.log(`processo filho finalizou com o código ${code}`)
})
Evento: 'disconnect'
Adicionado em: v0.7.2
O evento 'disconnect'
é emitido após chamar o método subprocess.disconnect()
no processo pai ou process.disconnect()
no processo filho. Depois de desconectar, não é mais possível enviar ou receber mensagens, e a propriedade subprocess.connected
é false
.
Evento: 'error'
err
<Error> O erro.
O evento 'error'
é emitido sempre que:
- O processo não pôde ser iniciado.
- O processo não pôde ser finalizado.
- O envio de uma mensagem para o processo filho falhou.
- O processo filho foi abortado por meio da opção
signal
.
O evento 'exit'
pode ou não ser disparado após a ocorrência de um erro. Ao escutar os eventos 'exit'
e 'error'
, proteja-se contra a invocação acidental de funções de manipulador várias vezes.
Veja também subprocess.kill()
e subprocess.send()
.
Evento: 'exit'
Adicionado em: v0.1.90
code
<number> O código de saída se o processo filho foi encerrado por conta própria.signal
<string> O sinal pelo qual o processo filho foi terminado.
O evento 'exit'
é emitido após o término do processo filho. Se o processo foi encerrado, code
é o código de saída final do processo, caso contrário, null
. Se o processo foi encerrado devido ao recebimento de um sinal, signal
é o nome da string do sinal, caso contrário, null
. Um dos dois sempre será não-null
.
Quando o evento 'exit'
é disparado, os fluxos stdio do processo filho ainda podem estar abertos.
O Node.js estabelece manipuladores de sinal para SIGINT
e SIGTERM
e os processos do Node.js não serão encerrados imediatamente devido ao recebimento desses sinais. Em vez disso, o Node.js executará uma sequência de ações de limpeza e, em seguida, levantará novamente o sinal tratado.
Veja waitpid(2)
.
Evento: 'message'
Adicionado em: v0.5.9
message
<Objeto> Um objeto JSON analisado ou valor primitivo.sendHandle
<Handle> | <undefined>undefined
ou um objetonet.Socket
,net.Server
oudgram.Socket
.
O evento 'message'
é disparado quando um processo filho usa process.send()
para enviar mensagens.
A mensagem passa por serialização e análise. A mensagem resultante pode não ser a mesma que foi enviada originalmente.
Se a opção serialization
foi definida como 'advanced'
usada ao criar o processo filho, o argumento message
pode conter dados que o JSON não consegue representar. Consulte Serialização avançada para obter mais detalhes.
Evento: 'spawn'
Adicionado em: v15.1.0, v14.17.0
O evento 'spawn'
é emitido assim que o processo filho é criado com sucesso. Se o processo filho não for criado com sucesso, o evento 'spawn'
não é emitido e o evento 'error'
é emitido em seu lugar.
Se emitido, o evento 'spawn'
ocorre antes de todos os outros eventos e antes que qualquer dado seja recebido via stdout
ou stderr
.
O evento 'spawn'
será acionado, independentemente de ocorrer um erro dentro do processo criado. Por exemplo, se bash some-command
for criado com sucesso, o evento 'spawn'
será acionado, embora bash
possa falhar ao criar some-command
. Essa ressalva também se aplica ao usar { shell: true }
.
subprocess.channel
[Histórico]
Versão | Alterações |
---|---|
v14.0.0 | O objeto não expõe mais acidentalmente ligações nativas C++. |
v7.1.0 | Adicionado em: v7.1.0 |
- <Objeto> Um pipe representando o canal IPC para o processo filho.
A propriedade subprocess.channel
é uma referência ao canal IPC do filho. Se não existir um canal IPC, esta propriedade será undefined
.
subprocess.channel.ref()
Adicionado em: v7.1.0
Este método faz com que o canal IPC mantenha o loop de eventos do processo pai em execução se .unref()
tiver sido chamado antes.
subprocess.channel.unref()
Adicionado em: v7.1.0
Este método faz com que o canal IPC não mantenha o loop de eventos do processo pai em execução e permite que ele termine mesmo enquanto o canal estiver aberto.
subprocess.connected
Adicionado em: v0.7.2
- <boolean> Definido como
false
apóssubprocess.disconnect()
ser chamado.
A propriedade subprocess.connected
indica se ainda é possível enviar e receber mensagens de um processo filho. Quando subprocess.connected
é false
, não é mais possível enviar ou receber mensagens.
subprocess.disconnect()
Adicionado em: v0.7.2
Fecha o canal IPC entre os processos pai e filho, permitindo que o processo filho saia normalmente quando não houver outras conexões mantendo-o ativo. Depois de chamar este método, as propriedades subprocess.connected
e process.connected
nos processos pai e filho (respectivamente) serão definidas como false
e não será mais possível passar mensagens entre os processos.
O evento 'disconnect'
será emitido quando não houver mensagens em processo de recebimento. Isso geralmente será acionado imediatamente após chamar subprocess.disconnect()
.
Quando o processo filho for uma instância Node.js (por exemplo, gerado usando child_process.fork()
), o método process.disconnect()
pode ser invocado dentro do processo filho para fechar o canal IPC também.
subprocess.exitCode
A propriedade subprocess.exitCode
indica o código de saída do processo filho. Se o processo filho ainda estiver em execução, o campo será null
.
subprocess.kill([signal])
Adicionado em: v0.1.90
O método subprocess.kill()
envia um sinal para o processo filho. Se nenhum argumento for fornecido, o sinal 'SIGTERM'
será enviado ao processo. Veja signal(7)
para uma lista de sinais disponíveis. Esta função retorna true
se kill(2)
for bem-sucedido e false
caso contrário.
const { spawn } = require('node:child_process')
const grep = spawn('grep', ['ssh'])
grep.on('close', (code, signal) => {
console.log(`processo filho terminado devido ao recebimento do sinal ${signal}`)
})
// Enviar SIGHUP para o processo.
grep.kill('SIGHUP')
import { spawn } from 'node:child_process'
const grep = spawn('grep', ['ssh'])
grep.on('close', (code, signal) => {
console.log(`processo filho terminado devido ao recebimento do sinal ${signal}`)
})
// Enviar SIGHUP para o processo.
grep.kill('SIGHUP')
O objeto ChildProcess
pode emitir um evento 'error'
se o sinal não puder ser entregue. Enviar um sinal para um processo filho que já foi encerrado não é um erro, mas pode ter consequências imprevistas. Especificamente, se o identificador de processo (PID) tiver sido reatribuído a outro processo, o sinal será entregue a esse processo, o que pode ter resultados inesperados.
Embora a função seja chamada de kill
, o sinal entregue ao processo filho pode não encerrar o processo.
Consulte kill(2)
para referência.
No Windows, onde os sinais POSIX não existem, o argumento signal
será ignorado, exceto para 'SIGKILL'
, 'SIGTERM'
, 'SIGINT'
e 'SIGQUIT'
, e o processo será sempre encerrado de forma forçada e abrupta (semelhante a 'SIGKILL'
). Veja Eventos de Sinal para mais detalhes.
No Linux, os processos filhos de processos filhos não serão encerrados ao tentar encerrar seu pai. É provável que isso aconteça ao executar um novo processo em um shell ou com o uso da opção shell
de ChildProcess
:
const { spawn } = require('node:child_process')
const subprocess = spawn(
'sh',
[
'-c',
`node -e "setInterval(() => {
console.log(process.pid, 'está vivo')
}, 500);"`,
],
{
stdio: ['inherit', 'inherit', 'inherit'],
}
)
setTimeout(() => {
subprocess.kill() // Não encerra o processo Node.js no shell.
}, 2000)
import { spawn } from 'node:child_process'
const subprocess = spawn(
'sh',
[
'-c',
`node -e "setInterval(() => {
console.log(process.pid, 'está vivo')
}, 500);"`,
],
{
stdio: ['inherit', 'inherit', 'inherit'],
}
)
setTimeout(() => {
subprocess.kill() // Não encerra o processo Node.js no shell.
}, 2000)
subprocess[Symbol.dispose]()
Adicionado em: v20.5.0, v18.18.0
[Estável: 1 - Experimental]
Estável: 1 Estabilidade: 1 - Experimental
Chama subprocess.kill()
com 'SIGTERM'
.
subprocess.killed
Adicionado em: v0.5.10
- <boolean> Definido como
true
depois quesubprocess.kill()
é usado para enviar um sinal com sucesso para o processo filho.
A propriedade subprocess.killed
indica se o processo filho recebeu um sinal com sucesso de subprocess.kill()
. A propriedade killed
não indica que o processo filho foi encerrado.
subprocess.pid
Adicionado em: v0.1.90
Retorna o identificador de processo (PID) do processo filho. Se o processo filho não conseguir ser gerado devido a erros, o valor será undefined
e error
será emitido.
const { spawn } = require('node:child_process')
const grep = spawn('grep', ['ssh'])
console.log(`PID do filho gerado: ${grep.pid}`)
grep.stdin.end()
import { spawn } from 'node:child_process'
const grep = spawn('grep', ['ssh'])
console.log(`PID do filho gerado: ${grep.pid}`)
grep.stdin.end()
subprocess.ref()
Adicionado em: v0.7.10
Chamar subprocess.ref()
depois de fazer uma chamada para subprocess.unref()
restaurará a contagem de referência removida para o processo filho, forçando o processo pai a esperar que o processo filho saia antes de sair ele mesmo.
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])
[Histórico]
Versão | Mudanças |
---|---|
v5.8.0 | O parâmetro options , e a opção keepOpen em particular, são suportados agora. |
v5.0.0 | Este método agora retorna um booleano para controle de fluxo. |
v4.0.0 | O parâmetro callback agora é suportado. |
v0.5.9 | Adicionado em: v0.5.9 |
message
<Object>sendHandle
<Handle> | <undefined>undefined
, ou um objetonet.Socket
,net.Server
, oudgram.Socket
.options
<Object> O argumentooptions
, se presente, é um objeto usado para parametrizar o envio de certos tipos de handles.options
suporta as seguintes propriedades:keepOpen
<boolean> Um valor que pode ser usado ao passar instâncias denet.Socket
. Quandotrue
, o socket é mantido aberto no processo de envio. Padrão:false
.
callback
<Function>Retorna: <boolean>
Quando um canal IPC foi estabelecido entre os processos pai e filho (ou seja, ao usar child_process.fork()
), o método subprocess.send()
pode ser usado para enviar mensagens para o processo filho. Quando o processo filho é uma instância Node.js, essas mensagens podem ser recebidas através do evento 'message'
.
A mensagem passa por serialização e análise. A mensagem resultante pode não ser a mesma do que a enviada originalmente.
Por exemplo, no script pai:
const { fork } = require('node:child_process')
const forkedProcess = fork(`${__dirname}/sub.js`)
forkedProcess.on('message', message => {
console.log('PAI recebeu mensagem:', message)
})
// Faz com que o filho imprima: FILHO recebeu mensagem: { 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('PAI recebeu mensagem:', message)
})
// Faz com que o filho imprima: FILHO recebeu mensagem: { hello: 'world' }
forkedProcess.send({ hello: 'world' })
E então o script filho, 'sub.js'
pode ser semelhante a este:
process.on('message', message => {
console.log('FILHO recebeu mensagem:', message)
})
// Faz com que o pai imprima: PAI recebeu mensagem: { foo: 'bar', baz: null }
process.send({ foo: 'bar', baz: NaN })
Processos filho Node.js terão um método process.send()
próprio que permite que o processo filho envie mensagens de volta para o processo pai.
Há um caso especial ao enviar uma mensagem {cmd: 'NODE_foo'}
. Mensagens contendo um prefixo NODE_
na propriedade cmd
são reservadas para uso dentro do núcleo do Node.js e não serão emitidas no evento 'message'
do filho. Em vez disso, tais mensagens são emitidas usando o evento 'internalMessage'
e são consumidas internamente pelo Node.js. As aplicações devem evitar usar tais mensagens ou ouvir por eventos 'internalMessage'
, pois está sujeito a alterações sem aviso prévio.
O argumento opcional sendHandle
que pode ser passado para subprocess.send()
é para passar um servidor TCP ou objeto socket para o processo filho. O processo filho receberá o objeto como o segundo argumento passado para a função de callback registrada no evento 'message'
. Quaisquer dados que forem recebidos e armazenados em buffer no socket não serão enviados para o filho. O envio de sockets IPC não é suportado no Windows.
O callback
opcional é uma função que é invocada após a mensagem ser enviada, mas antes que o processo filho a tenha recebido. A função é chamada com um único argumento: null
em caso de sucesso ou um objeto Error
em caso de falha.
Se nenhuma função callback
for fornecida e a mensagem não puder ser enviada, um evento 'error'
será emitido pelo objeto ChildProcess
. Isso pode acontecer, por exemplo, quando o processo filho já saiu.
subprocess.send()
retornará false
se o canal tiver fechado ou quando o backlog de mensagens não enviadas exceder um limite que o torna imprudente enviar mais. Caso contrário, o método retorna true
. A função callback
pode ser usada para implementar o controle de fluxo.
Exemplo: enviando um objeto de servidor
O argumento sendHandle
pode ser usado, por exemplo, para passar o manipulador de um objeto de servidor TCP para o processo filho, conforme ilustrado no exemplo abaixo:
const { fork } = require('node:child_process')
const { createServer } = require('node:net')
const subprocess = fork('subprocess.js')
// Abre o objeto do servidor e envia o manipulador.
const server = createServer()
server.on('connection', socket => {
socket.end('manipulado pelo pai')
})
server.listen(1337, () => {
subprocess.send('server', server)
})
import { fork } from 'node:child_process'
import { createServer } from 'node:net'
const subprocess = fork('subprocess.js')
// Abre o objeto do servidor e envia o manipulador.
const server = createServer()
server.on('connection', socket => {
socket.end('manipulado pelo pai')
})
server.listen(1337, () => {
subprocess.send('server', server)
})
O processo filho receberia então o objeto do servidor como:
process.on('message', (m, server) => {
if (m === 'server') {
server.on('connection', socket => {
socket.end('manipulado pelo filho')
})
}
})
Uma vez que o servidor agora é compartilhado entre o pai e o filho, algumas conexões podem ser tratadas pelo pai e outras pelo filho.
Enquanto o exemplo acima usa um servidor criado usando o módulo node:net
, os servidores do módulo node:dgram
usam exatamente o mesmo fluxo de trabalho, com as exceções de escutar um evento 'message'
em vez de 'connection'
e usar server.bind()
em vez de server.listen()
. Isso, no entanto, é suportado apenas em plataformas Unix.
Exemplo: enviando um objeto de socket
Da mesma forma, o argumento sendHandler
pode ser usado para passar o manipulador de um socket para o processo filho. O exemplo abaixo gera dois filhos que tratam conexões com prioridade "normal" ou "especial":
const { fork } = require('node:child_process')
const { createServer } = require('node:net')
const normal = fork('subprocess.js', ['normal'])
const special = fork('subprocess.js', ['special'])
// Abre o servidor e envia os sockets para o filho. Use pauseOnConnect para impedir
// que os sockets sejam lidos antes de serem enviados para o processo filho.
const server = createServer({ pauseOnConnect: true })
server.on('connection', socket => {
// Se esta for prioridade especial...
if (socket.remoteAddress === '74.125.127.100') {
special.send('socket', socket)
return
}
// Esta é prioridade normal.
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'])
// Abre o servidor e envia os sockets para o filho. Use pauseOnConnect para impedir
// que os sockets sejam lidos antes de serem enviados para o processo filho.
const server = createServer({ pauseOnConnect: true })
server.on('connection', socket => {
// Se esta for prioridade especial...
if (socket.remoteAddress === '74.125.127.100') {
special.send('socket', socket)
return
}
// Esta é prioridade normal.
normal.send('socket', socket)
})
server.listen(1337)
O subprocess.js
receberia o manipulador de socket como o segundo argumento passado para a função de retorno de chamada do evento:
process.on('message', (m, socket) => {
if (m === 'socket') {
if (socket) {
// Verifique se o socket do cliente existe.
// É possível que o socket seja fechado entre o momento em que é
// enviado e o momento em que é recebido no processo filho.
socket.end(`Pedido tratado com prioridade ${process.argv[2]}`)
}
}
})
Não use .maxConnections
em um socket que foi passado para um subprocesso. O pai não pode rastrear quando o socket é destruído.
Qualquer manipulador 'message'
no subprocesso deve verificar se o socket
existe, pois a conexão pode ter sido fechada durante o tempo que leva para enviar a conexão para o filho.
subprocess.signalCode
A propriedade subprocess.signalCode
indica o sinal recebido pelo processo filho, se houver, caso contrário, null
.
subprocess.spawnargs
A propriedade subprocess.spawnargs
representa a lista completa de argumentos de linha de comando com os quais o processo filho foi iniciado.
subprocess.spawnfile
A propriedade subprocess.spawnfile
indica o nome do arquivo executável do processo filho que é iniciado.
Para child_process.fork()
, seu valor será igual a process.execPath
. Para child_process.spawn()
, seu valor será o nome do arquivo executável. Para child_process.exec()
, seu valor será o nome do shell no qual o processo filho é iniciado.
subprocess.stderr
Adicionado em: v0.1.90
Um Readable Stream
que representa o stderr
do processo filho.
Se o processo filho foi gerado com stdio[2]
definido para algo diferente de 'pipe'
, então isso será null
.
subprocess.stderr
é um alias para subprocess.stdio[2]
. Ambas as propriedades se referirão ao mesmo valor.
A propriedade subprocess.stderr
pode ser null
ou undefined
se o processo filho não pôde ser gerado com sucesso.
subprocess.stdin
Adicionado em: v0.1.90
Um Writable Stream
que representa o stdin
do processo filho.
Se um processo filho aguarda a leitura de toda a sua entrada, o processo filho não continuará até que este fluxo tenha sido fechado via end()
.
Se o processo filho foi gerado com stdio[0]
definido para algo diferente de 'pipe'
, então isso será null
.
subprocess.stdin
é um alias para subprocess.stdio[0]
. Ambas as propriedades se referirão ao mesmo valor.
A propriedade subprocess.stdin
pode ser null
ou undefined
se o processo filho não pôde ser gerado com sucesso.
subprocess.stdio
Adicionado em: v0.7.10
Um array esparso de pipes para o processo filho, correspondendo às posições na opção stdio
passada para child_process.spawn()
que foram definidas para o valor 'pipe'
. subprocess.stdio[0]
, subprocess.stdio[1]
e subprocess.stdio[2]
também estão disponíveis como subprocess.stdin
, subprocess.stdout
e subprocess.stderr
, respectivamente.
No exemplo a seguir, apenas o fd 1
(stdout) do filho é configurado como um pipe, portanto, apenas o subprocess.stdio[1]
do pai é um fluxo, todos os outros valores na array são 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, // Use o stdin do pai para o filho.
'pipe', // Direciona o stdout do filho para o pai.
fs.openSync('err.out', 'w'), // Direciona o stderr do filho para um arquivo.
],
})
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, // Use o stdin do pai para o filho.
'pipe', // Direciona o stdout do filho para o pai.
fs.openSync('err.out', 'w'), // Direciona o stderr do filho para um arquivo.
],
})
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)
A propriedade subprocess.stdio
pode ser undefined
se o processo filho não pôde ser gerado com sucesso.
subprocess.stdout
Adicionado em: v0.1.90
Um Readable Stream
que representa o stdout
do processo filho.
Se o processo filho foi gerado com stdio[1]
definido para algo diferente de 'pipe'
, então isso será null
.
subprocess.stdout
é um alias para subprocess.stdio[1]
. Ambas as propriedades se referirão ao mesmo valor.
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}`)
})
A propriedade subprocess.stdout
pode ser null
ou undefined
se o processo filho não pôde ser gerado com sucesso.
subprocess.unref()
Adicionado em: v0.7.10
Por padrão, o processo pai esperará que o processo filho separado seja encerrado. Para impedir que o processo pai espere que um determinado subprocess
seja encerrado, use o método subprocess.unref()
. Isso fará com que o loop de eventos do pai não inclua o processo filho em sua contagem de referência, permitindo que o pai seja encerrado independentemente do filho, a menos que haja um canal IPC estabelecido entre o filho e os processos pai.
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
A opção maxBuffer
especifica o maior número de bytes permitidos em stdout
ou stderr
. Se este valor for excedido, o processo filho é terminado. Isso afeta a saída que inclui codificações de caracteres multibyte, como UTF-8 ou UTF-16. Por exemplo, console.log('中文测试')
enviará 13 bytes codificados em UTF-8 para stdout
, embora haja apenas 4 caracteres.
Requisitos do Shell
O shell deve entender a opção -c
. Se o shell for 'cmd.exe'
, ele deve entender as opções /d /s /c
e a análise da linha de comando deve ser compatível.
Shell padrão do Windows
Embora a Microsoft especifique que %COMSPEC%
deve conter o caminho para 'cmd.exe'
no ambiente raiz, os processos filhos nem sempre estão sujeitos ao mesmo requisito. Assim, nas funções child_process
onde um shell pode ser gerado, 'cmd.exe'
é usado como fallback se process.env.ComSpec
não estiver disponível.
Serialização avançada
Adicionado em: v13.2.0, v12.16.0
Processos filhos suportam um mecanismo de serialização para IPC que é baseado na API de serialização do módulo node:v8
, baseado no algoritmo de clonagem estruturada HTML. Isso geralmente é mais poderoso e suporta mais tipos de objetos JavaScript internos, como BigInt
, Map
e Set
, ArrayBuffer
e TypedArray
, Buffer
, Error
, RegExp
etc.
No entanto, este formato não é um superconjunto completo de JSON e, por exemplo, propriedades definidas em objetos de tais tipos internos não serão passadas pela etapa de serialização. Além disso, o desempenho pode não ser equivalente ao do JSON, dependendo da estrutura dos dados passados. Portanto, este recurso requer adesão definindo a opção serialization
para 'advanced'
ao chamar child_process.spawn()
ou child_process.fork()
.