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, a 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, 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 no stdout além desse limite sem que a saída seja capturada, o subprocesso será bloqueado aguardando que o buffer do pipe aceite mais dados. Isso é idêntico ao comportamento dos pipes no shell. Use a opção { stdio: 'ignore' }
se a saída não for consumida.
A pesquisa de comando é 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 corresponda sem distinção entre maiúsculas e 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 possuem 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 maneira 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 sobre child_process.spawn()
ou child_process.spawnSync()
.
child_process.exec()
: gera um shell e executa um comando dentro desse shell, passando ostdout
estderr
para uma função de callback 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 à paralisação 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 idiomático de programação assíncrona 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 de callback
opcional seja especificada, a qual é invocada quando o processo filho é finalizado.
Iniciando 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), 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 precisa 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 | Suporte para AbortSignal foi adicionado. |
v16.4.0, v14.18.0 | A opção cwd pode ser um objeto URL WHATWG 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 para executar, 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 com. Veja Requisitos do 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 é 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
.
callback
<Function> chamada com a saída quando o processo termina.Retorna: <ChildProcess>
Inicia um shell e então 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 dependendo do shell) precisam ser tratados adequadamente:
const { exec } = require('node:child_process');
exec('"/path/to/test file/test.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 "The \\$HOME variable is $HOME"');
// A variável $HOME é escapada na primeira instância, mas não na segunda.
import { exec } from 'node:child_process';
exec('"/path/to/test file/test.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 "The \\$HOME variable is $HOME"');
// A variável $HOME é escapada na primeira instância, mas não na segunda.
Nunca passe entrada de usuário não tratada para esta função. Qualquer entrada contendo metacaracteres do shell pode ser usada para acionar a execução arbitrária de comandos.
Se uma função callback
for fornecida, ela é 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 missing_file | wc -l', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});
import { exec } from 'node:child_process';
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});
Se timeout
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 de 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 retorna uma Promise
para um Object
com propriedades stdout
e stderr
. A instância ChildProcess
retornada é anexada à Promise
como uma propriedade child
. No caso de um erro (incluindo qualquer erro que resulte 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 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 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); // an AbortError
});
controller.abort();
import { exec } from 'node:child_process';
const controller = new AbortController();
const { signal } = controller;
const child = exec('grep ssh', { signal }, (error) => {
console.error(error); // an AbortError
});
controller.abort();
child_process.execFile(file[, args][, options][, callback])
[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.4.0, v14.17.0 | Suporte para AbortSignal foi adicionado. |
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 de 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 não gera um shell por padrão. Em vez disso, o file
executável especificado é gerado diretamente como um novo processo, tornando-o ligeiramente 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 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 em vez disso.
Se este método for invocado como sua versão util.promisify()
ed, ele retorna 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 resultante 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 entrada do usuário não sanitizada para esta função. Qualquer entrada contendo metacaracteres de shell pode ser usada para acionar execução de comando arbitrário.
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); // an AbortError
});
controller.abort();
import { execFile } from 'node:child_process';
const controller = new AbortController();
const { signal } = controller;
const child = execFile('node', ['--version'], { signal }, (error) => {
console.error(error); // an AbortError
});
controller.abort();
child_process.fork(modulePath[, args][, options])
[Histórico]
Versão | Mudanças |
---|---|
v17.4.0, v16.14.0 | O parâmetro modulePath pode ser um objeto WHATWG URL usando o protocolo file: . |
v16.4.0, v14.18.0 | A opção cwd pode ser um objeto WHATWG URL usando o protocolo file: . |
v15.13.0, v14.18.0 | timeout foi adicionado. |
v15.11.0, v14.18.0 | killSignal para AbortSignal foi adicionado. |
v15.6.0, v14.17.0 | O suporte ao 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> Prepara 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 do 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 morto por timeout ou sinal de aborto. Padrão:'SIGTERM'
.silent
<boolean> Setrue
, stdin, stdout e stderr do processo filho serão canalizados para o processo pai, caso contrário, eles serão herdados do processo pai, consulte as opções'pipe'
e'inherit'
para ochild_process.spawn()
'sstdio
para obter mais detalhes. Padrão:false
.stdio
<Array> | <string> Consulte ostdio
dochild_process.spawn()
. Quando esta opção é fornecida, ela substituisilent
. Se a variante de matriz for usada, ela deve conter exatamente um item com 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, a quantidade máxima de tempo 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 Node.js. Como child_process.spawn()
, um objeto ChildProcess
é retornado. O ChildProcess
retornado terá um canal de comunicação adicional integrado que permite que mensagens sejam passadas de um lado para o outro entre o pai e o filho. Consulte subprocess.send()
para obter detalhes.
Lembre-se de que os processos filho 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 é recomendável gerar um grande número de processos filho 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 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 de 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(`Hello from ${process.argv[2]}!`);
}, 1_000);
} else {
const controller = new AbortController();
const { signal } = controller;
const child = fork(__filename, ['child'], { signal });
child.on('error', (err) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process
}
import { fork } from 'node:child_process';
import process from 'node:process';
if (process.argv[2] === 'child') {
setTimeout(() => {
console.log(`Hello from ${process.argv[2]}!`);
}, 1_000);
} else {
const controller = new AbortController();
const { signal } = controller;
const child = fork(import.meta.url, ['child'], { signal });
child.on('error', (err) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process
}
child_process.spawn(command[, args][, options])
[Histórico]
Versão | Alterações |
---|---|
v16.4.0, v14.18.0 | A opção cwd pode ser um objeto WHATWG URL usando o protocolo file: . |
v15.13.0, v14.18.0 | timeout 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 do ambiente. Padrão:process.env
.argv0
<string> Define explicitamente o valor deargv[0]
enviado ao processo filho. Isso será definido comocommand
se não for especificado.stdio
<Array> | <string> Configuração stdio do filho (veroptions.stdio
).detached
<boolean> Prepara o processo filho para ser executado independentemente de seu processo pai. O comportamento específico depende da plataforma, veroptions.detached
).uid
<number> Define a identidade do usuário do processo (versetuid(2)
).gid
<number> Define a identidade do grupo do processo (versetgid(2)
).serialization
<string> Especifica o tipo de serialização usado para enviar mensagens entre processos. Os valores possíveis são'json'
e'advanced'
. Ver Serialização avançada para 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. Ver 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 eliminado 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
assume o padrão de um array vazio.
Se a opção shell
estiver ativada, não passe entrada de usuário não tratada para esta função. Qualquer entrada que contenha metacaracteres de 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 estes padrões:
const defaults = {
cwd: undefined,
env: process.env,
};
Use cwd
para especificar o diretório de trabalho 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 estarã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 ativada, chamar .abort()
no AbortController
correspondente é semelhante a chamar .kill()
no processo filho, exceto que o erro passado para o callback 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) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process
import { spawn } from 'node:child_process';
const controller = new AbortController();
const { signal } = controller;
const grep = spawn('grep', ['ssh'], { signal });
grep.on('error', (err) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process
options.detached
Adicionado em: v0.7.10
No Windows, definir options.detached
como true
permite que o processo filho continue a ser executado após a saída 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 será transformado no líder de um novo grupo de processos e sessão. Processos filhos podem continuar sendo executados após a saída do pai, independentemente de estarem separados ou não. Veja setsid(2)
para mais informações.
Por padrão, o pai esperará que o processo filho separado saia. Para impedir que o processo pai espere que um determinado subprocess
saia, use o método subprocess.unref()
. Fazer 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 os processos filho e pai.
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, separando e também ignorando seus descritores de arquivo stdio
pai, para ignorar o término 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 | Mudanças |
---|---|
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 streams correspondentes subprocess.stdin
, subprocess.stdout
e subprocess.stderr
no objeto ChildProcess
. Isso é equivalente a definir options.stdio
como ['pipe', 'pipe', 'pipe']
.
Para 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');
// Filho usará os stdios do pai.
spawn('prg', [], { stdio: 'inherit' });
// Iniciar filho compartilhando apenas stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });
// Abra um fd=4 extra para interagir com programas que apresentam uma
// interface estilo startd.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });
import { spawn } from 'node:child_process';
import process from 'node:process';
// Filho usará os stdios do pai.
spawn('prg', [], { stdio: 'inherit' });
// Iniciar filho compartilhando apenas stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });
// Abra um fd=4 extra para interagir com programas que apresentam 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 processos síncronos
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 estas 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 WHATWG URL 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 definida explicitamente para 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]
for definido como'pipe'
, o fornecimento deste valor substituirástdio[0]
.stdio
<string> | <Array> Configuração do stdio do filho. Veja ostdio
dechild_process.spawn()
.stderr
por padrão será saída para o stderr do processo pai, a menos questdio
seja especificado. Padrão:'pipe'
.env
<Object> Pares de valores-chave 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 for morto. Padrão:'SIGTERM'
.maxBuffer
<number> Maior quantidade de dados em bytes permitidos em stdout ou stderr. Se excedido, o processo filho é encerrado. 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
.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).
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 tenha sido totalmente fechado. Quando um tempo limite é encontrado e killSignal
é enviado, o método não retornará até que o processo tenha saído completamente.
Se o processo filho interceptar e manipular o sinal SIGTERM
e não sair, o processo pai ainda esperará até que o processo filho tenha saído.
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 entrada de usuário não higienizada 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 streaming de stderr filho para o stderr pai
stdio: 'pipe',
// Usa codificação utf8 para pipes stdio
encoding: 'utf8',
});
console.log(stdout);
} catch (err) {
if (err.code) {
// Falha ao gerar processo filho
console.error(err.code);
} else {
// 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 streaming de stderr filho para o stderr pai
stdio: 'pipe',
// Usa codificação utf8 para pipes stdio
encoding: 'utf8',
});
console.log(stdout);
} catch (err) {
if (err.code) {
// Falha ao gerar processo filho
console.error(err.code);
} else {
// 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 WHATWG URL 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 . |
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 este valor substituirástdio[0]
.stdio
<string> | <Array> Configuração de stdio do filho. Veja 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 do ambiente. Padrão:process.env
.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.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 for terminado. Padrão:'SIGTERM'
.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
.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
.
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 totalmente fechado. Quando um timeout é 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 for encerrado, o processo pai 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 erro. O objeto Error
conterá o resultado inteiro de child_process.spawnSync()
.
Nunca passe entradas de usuário não higienizadas para esta função. Qualquer entrada contendo metacaracteres de shell podem ser usados para acionar a execução de comandos arbitrários.
child_process.spawnSync(command[, args][, options])
[Histórico]
Versão | Alterações |
---|---|
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 . |
v5.7.0 | A opção shell agora é suportada. |
v6.2.1, v4.5.0 | A opção encoding agora pode ser definida explicitamente 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'
, o fornecimento desse 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. Consulte ostdio
dechild_process.spawn()
. Padrão:'pipe'
.env
<Object> Pares de chave-valor do 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 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 o aviso 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 terminou devido a um sinal.signal
<string> | <null> O sinal usado para matar o subprocesso, ounull
se o subprocesso não terminou 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 sido completamente encerrado. Se o processo interceptar e manipular o sinal SIGTERM
e não for encerrado, o processo pai aguardará até que o processo filho seja encerrado.
Se a opção shell
estiver habilitada, não passe entrada do usuário não higienizada para esta função. Qualquer entrada que contenha metacaracteres de shell pode ser usada para acionar a execução arbitrária de comandos.
Classe: ChildProcess
Adicionado em: v2.2.0
- Estende: <EventEmitter>
Instâncias de ChildProcess
representam processos filhos gerados.
As instâncias de ChildProcess
não devem ser 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 foi encerrado por conta própria.signal
<string> O sinal pelo qual o processo filho foi encerrado.
O evento 'close'
é emitido depois que um processo é encerrado e os fluxos stdio de um processo filho são fechados. Isso é diferente do evento 'exit'
, já que vários processos podem compartilhar os mesmos fluxos stdio. O evento 'close'
sempre será emitido 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(`child process close all stdio with code ${code}`);
});
ls.on('exit', (code) => {
console.log(`child process exited with code ${code}`);
});
import { spawn } from 'node:child_process';
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`);
});
ls.on('exit', (code) => {
console.log(`child process exited with code ${code}`);
});
Evento: 'disconnect'
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. Após a desconexão, 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 terminado.
- O envio de uma mensagem para o processo filho falhou.
- O processo filho foi abortado através 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 tratamento múltiplas 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 saiu 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 terminou 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, relançará o sinal tratado.
Veja waitpid(2)
.
Evento: 'message'
Adicionado em: v0.5.9
message
<Object> Um objeto JSON analisado ou valor primitivo.sendHandle
<Handle> | <undefined>undefined
ou um objetonet.Socket
,net.Server
, oudgram.Socket
.
O evento 'message'
é acionado 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'
quando o processo filho foi gerado, o argumento message
pode conter dados que o JSON não consegue representar. Veja Serialização avançada para mais detalhes.
Evento: 'spawn'
Adicionado em: v15.1.0, v14.17.0
O evento 'spawn'
é emitido assim que o processo filho é gerado com sucesso. Se o processo filho não for gerado com sucesso, o evento 'spawn'
não será emitido e o evento 'error'
será emitido em vez disso.
Se emitido, o evento 'spawn'
vem 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 ou não um erro dentro do processo gerado. Por exemplo, se bash some-command
for gerado com sucesso, o evento 'spawn'
será acionado, embora bash
possa falhar ao gerar some-command
. Essa ressalva também se aplica ao usar { shell: true }
.
subprocess.channel
[Histórico]
Versão | Mudanças |
---|---|
v14.0.0 | O objeto não expõe mais acidentalmente bindings C++ nativas. |
v7.1.0 | Adicionado em: v7.1.0 |
- <Object> Um pipe representando o canal IPC para o processo filho.
A propriedade subprocess.channel
é uma referência ao canal IPC do filho. Se nenhum canal IPC existir, essa propriedade é 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 está aberto.
subprocess.connected
Adicionado em: v0.7.2
- <boolean> Definido como
false
depois quesubprocess.disconnect()
é 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 no processo de serem recebidas. Isso geralmente será acionado imediatamente após chamar subprocess.disconnect()
.
Quando o processo filho é uma instância do Node.js (por exemplo, gerada 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. Consulte signal(7)
para obter uma lista de sinais disponíveis. Esta função retorna true
se kill(2)
for bem-sucedida e false
caso contrário.
const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);
grep.on('close', (code, signal) => {
console.log(
`child process terminated due to receipt of signal ${signal}`);
});
// Send SIGHUP to process.
grep.kill('SIGHUP');
import { spawn } from 'node:child_process';
const grep = spawn('grep', ['ssh']);
grep.on('close', (code, signal) => {
console.log(
`child process terminated due to receipt of signal ${signal}`);
});
// Send SIGHUP to process.
grep.kill('SIGHUP');
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 do processo (PID) foi 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 terminar 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 sempre será encerrado à força e abruptamente (semelhante a 'SIGKILL'
). Consulte Eventos de Sinal para obter 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, 'is alive')
}, 500);"`,
], {
stdio: ['inherit', 'inherit', 'inherit'],
},
);
setTimeout(() => {
subprocess.kill(); // Does not terminate the Node.js process in the shell.
}, 2000);
import { spawn } from 'node:child_process';
const subprocess = spawn(
'sh',
[
'-c',
`node -e "setInterval(() => {
console.log(process.pid, 'is alive')
}, 500);"`,
], {
stdio: ['inherit', 'inherit', 'inherit'],
},
);
setTimeout(() => {
subprocess.kill(); // Does not terminate the Node.js process in the shell.
}, 2000);
subprocess[Symbol.dispose]()
Adicionado em: v20.5.0, v18.18.0
[Stable: 1 - Experimental]
Stable: 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 com sucesso um sinal para o processo filho.
A propriedade subprocess.killed
indica se o processo filho recebeu com sucesso um sinal de subprocess.kill()
. A propriedade killed
não indica que o processo filho foi terminado.
subprocess.pid
Adicionado em: v0.1.90
Retorna o identificador do processo (PID) do processo filho. Se o processo filho não conseguir ser iniciado 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()
após fazer uma chamada para subprocess.unref()
irá restaurar a contagem de referência removida para o processo filho, forçando o processo pai a esperar que o processo filho termine antes de sair.
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 agora suportados. |
v5.0.0 | Este método retorna um booleano para controle de fluxo agora. |
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 (isto é, 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 do 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 que foi originalmente enviada.
Por exemplo, no script pai:
const { fork } = require('node:child_process');
const forkedProcess = fork(`${__dirname}/sub.js`);
forkedProcess.on('message', (message) => {
console.log('PARENT got message:', message);
});
// Causes the child to print: CHILD got message: { hello: 'world' }
forkedProcess.send({ hello: 'world' });
import { fork } from 'node:child_process';
const forkedProcess = fork(`${import.meta.dirname}/sub.js`);
forkedProcess.on('message', (message) => {
console.log('PARENT got message:', message);
});
// Causes the child to print: CHILD got message: { hello: 'world' }
forkedProcess.send({ hello: 'world' });
E então o script filho, 'sub.js'
pode ser parecido com este:
process.on('message', (message) => {
console.log('CHILD got message:', message);
});
// Causes the parent to print: PARENT got message: { foo: 'bar', baz: null }
process.send({ foo: 'bar', baz: NaN });
Os processos filhos do 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'}
. As mensagens que contêm um prefixo NODE_
na propriedade cmd
são reservadas para uso no núcleo do Node.js e não serão emitidas no evento 'message'
do filho. Em vez disso, essas mensagens são emitidas usando o evento 'internalMessage'
e são consumidas internamente pelo Node.js. Os aplicativos devem evitar usar tais mensagens ou ouvir os eventos 'internalMessage'
, pois estão sujeitos 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 de 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 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á foi encerrado.
subprocess.send()
retornará false
se o canal tiver fechado ou quando o backlog de mensagens não enviadas exceder um limite que 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, como ilustrado no exemplo abaixo:
const { fork } = require('node:child_process');
const { createServer } = require('node:net');
const subprocess = fork('subprocess.js');
// Abra o objeto do servidor e envie o manipulador.
const server = createServer();
server.on('connection', (socket) => {
socket.end('handled by parent');
});
server.listen(1337, () => {
subprocess.send('server', server);
});
import { fork } from 'node:child_process';
import { createServer } from 'node:net';
const subprocess = fork('subprocess.js');
// Abra o objeto do servidor e envie o manipulador.
const server = createServer();
server.on('connection', (socket) => {
socket.end('handled by parent');
});
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('handled by child');
});
}
});
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.
Embora o exemplo acima use 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 ouvir um evento 'message'
em vez de 'connection'
e usar server.bind()
em vez de server.listen()
. No entanto, isso só é suportado 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 lidam com 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']);
// Abra o servidor e envie 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 é 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']);
// Abra o servidor e envie 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 é 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 callback 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(`Request handled with ${process.argv[2]} priority`);
}
}
});
Não use .maxConnections
em um socket que foi passado para um subprocesso. O pai não pode rastrear quando o socket é destruído.
Quaisquer manipuladores de 'message'
no subprocesso devem verificar se 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 qualquer valor 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 espera para ler toda a sua entrada, o processo filho não continuará até que este stream seja 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, então apenas o subprocess.stdio[1]
do pai é um stream, todos os outros valores no 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 parent's stdin for child.
'pipe', // Pipe child's stdout to parent.
fs.openSync('err.out', 'w'), // Direct child's stderr to a file.
],
});
assert.strictEqual(subprocess.stdio[0], null);
assert.strictEqual(subprocess.stdio[0], subprocess.stdin);
assert(subprocess.stdout);
assert.strictEqual(subprocess.stdio[1], subprocess.stdout);
assert.strictEqual(subprocess.stdio[2], null);
assert.strictEqual(subprocess.stdio[2], subprocess.stderr);
import assert from 'node:assert';
import fs from 'node:fs';
import child_process from 'node:child_process';
const subprocess = child_process.spawn('ls', {
stdio: [
0, // Use parent's stdin for child.
'pipe', // Pipe child's stdout to parent.
fs.openSync('err.out', 'w'), // Direct child's stderr to a file.
],
});
assert.strictEqual(subprocess.stdio[0], null);
assert.strictEqual(subprocess.stdio[0], subprocess.stdin);
assert(subprocess.stdout);
assert.strictEqual(subprocess.stdio[1], subprocess.stdout);
assert.strictEqual(subprocess.stdio[2], null);
assert.strictEqual(subprocess.stdio[2], subprocess.stderr);
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 puder ser gerado com sucesso.
subprocess.unref()
Adicionado em: v0.7.10
Por padrão, o processo pai esperará que o processo filho destacado seja encerrado. Para impedir que o processo pai espere que um determinado subprocess
seja encerrado, use o método subprocess.unref()
. Fazer 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 saia independentemente do filho, a menos que haja um canal IPC estabelecido entre os processos filho e 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 é encerrado. Isso impacta 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 existam 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
Os processos filhos suportam um mecanismo de serialização para IPC que é baseado na API de serialização do módulo node:v8
, com base no algoritmo de clone estruturado HTML. Isso é geralmente mais poderoso e suporta mais tipos de objetos JavaScript integrados, 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, as propriedades definidas em objetos de tais tipos integrados não serão transmitidas através da etapa de serialização. Além disso, o desempenho pode não ser equivalente ao do JSON, dependendo da estrutura dos dados transmitidos. Portanto, este recurso requer a ativação definindo a opção serialization
como 'advanced'
ao chamar child_process.spawn()
ou child_process.fork()
.