Skip to content

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():

js
const { spawn } = require('node:child_process')
const ls = spawn('ls', ['-lh', '/usr'])

ls.stdout.on('data', data => {
  console.log(`stdout: ${data}`)
})

ls.stderr.on('data', data => {
  console.error(`stderr: ${data}`)
})

ls.on('close', code => {
  console.log(`child process exited with code ${code}`)
})
js
import { spawn } from 'node:child_process'
const ls = spawn('ls', ['-lh', '/usr'])

ls.stdout.on('data', data => {
  console.log(`stdout: ${data}`)
})

ls.stderr.on('data', data => {
  console.error(`stderr: ${data}`)
})

ls.on('close', code => {
  console.log(`child process exited with code ${code}`)
})

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().

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.

js
// 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) => {
  // ...
})
js
// 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ãoMudanças
v15.4.0Adicionado suporte para AbortSignal.
v16.4.0, v14.18.0A opção cwd pode ser um objeto WHATWG URL usando o protocolo file:.
v8.8.0A opção windowsHide agora é suportada.
v0.1.90Adicionado em: v0.1.90

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:

js
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.
js
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.

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

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

js
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()
js
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ãoMudanças
v16.4.0, v14.18.0A opção cwd pode ser um objeto WHATWG URL usando o protocolo file:.
v15.4.0, v14.17.0Foi adicionado suporte para AbortSignal.
v8.8.0A opção windowsHide agora é suportada.
v0.1.91Adicionado 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 em maxBuffer e Unicode. Padrão: 1024 * 1024.
    • killSignal <string> | <integer> Padrão: 'SIGTERM'
    • uid <number> Define a identidade do usuário do processo (veja setuid(2)).
    • gid <number> Define a identidade do grupo do processo (veja setgid(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> Se true, executa command dentro de um shell. Usa '/bin/sh' no Unix e process.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.

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

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.

js
const util = require('node:util')
const execFile = util.promisify(require('node:child_process').execFile)
async function getVersion() {
  const { stdout } = await execFile('node', ['--version'])
  console.log(stdout)
}
getVersion()
js
import { promisify } from 'node:util'
import child_process from 'node:child_process'
const execFile = promisify(child_process.execFile)
async function getVersion() {
  const { stdout } = await execFile('node', ['--version'])
  console.log(stdout)
}
getVersion()

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:

js
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()
js
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ãoMudanças
v17.4.0, v16.14.0O parâmetro modulePath pode ser um objeto URL WHATWG usando o protocolo file:.
v16.4.0, v14.18.0A opção cwd pode ser um objeto URL WHATWG usando o protocolo file:.
v15.13.0, v14.18.0O timeout foi adicionado.
v15.11.0, v14.18.0killSignal para AbortSignal foi adicionado.
v15.6.0, v14.17.0O suporte a AbortSignal foi adicionado.
v13.2.0, v12.16.0A opção serialization agora é suportada.
v8.0.0A opção stdio agora pode ser uma string.
v6.4.0A opção stdio agora é suportada.
v0.5.0Adicionado 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, consulte options.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 (consulte setgid(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> Se true, 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' para child_process.spawn()'s stdio para obter mais detalhes. Padrão: false.
    • stdio <Array> | <string> Consulte child_process.spawn()'s stdio. Quando esta opção é fornecida, ela substitui silent. 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 (consulte setuid(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:

js
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
}
js
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ãoMudanças
v16.4.0, v14.18.0A opção cwd pode ser um objeto URL WHATWG usando o protocolo file:.
v15.13.0, v14.18.0O tempo limite foi adicionado.
v15.11.0, v14.18.0killSignal para AbortSignal foi adicionado.
v15.5.0, v14.17.0Suporte para AbortSignal foi adicionado.
v13.2.0, v12.16.0A opção serialization agora é suportada.
v8.8.0A opção windowsHide agora é suportada.
v6.4.0A opção argv0 agora é suportada.
v5.7.0A opção shell agora é suportada.
v0.1.90Adicionado 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 de argv[0] enviado para o processo filho. Isso será definido como command se não for especificado.
    • stdio <Array> | <string> Configuração do stdio do filho (consulte options.stdio).
    • detached <boolean> Prepara o processo filho para ser executado independentemente de seu processo pai. O comportamento específico depende da plataforma, consulte options.detached).
    • uid <number> Define a identidade do usuário do processo (consulte setuid(2)).
    • gid <number> Define a identidade do grupo do processo (consulte setgid(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> Se true, executa command dentro de um shell. Usa '/bin/sh' no Unix e process.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 como true automaticamente quando shell é 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:

js
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:

js
const { spawn } = require('node:child_process')
const ls = spawn('ls', ['-lh', '/usr'])

ls.stdout.on('data', data => {
  console.log(`stdout: ${data}`)
})

ls.stderr.on('data', data => {
  console.error(`stderr: ${data}`)
})

ls.on('close', code => {
  console.log(`child process exited with code ${code}`)
})
js
import { spawn } from 'node:child_process'
const ls = spawn('ls', ['-lh', '/usr'])

ls.stdout.on('data', data => {
  console.log(`stdout: ${data}`)
})

ls.stderr.on('data', data => {
  console.error(`stderr: ${data}`)
})

ls.on('close', code => {
  console.log(`child process exited with code ${code}`)
})

Exemplo: Uma maneira muito elaborada de executar ps ax | grep ssh

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

ps.stdout.on('data', data => {
  grep.stdin.write(data)
})

ps.stderr.on('data', data => {
  console.error(`ps stderr: ${data}`)
})

ps.on('close', code => {
  if (code !== 0) {
    console.log(`ps process exited with code ${code}`)
  }
  grep.stdin.end()
})

grep.stdout.on('data', data => {
  console.log(data.toString())
})

grep.stderr.on('data', data => {
  console.error(`grep stderr: ${data}`)
})

grep.on('close', code => {
  if (code !== 0) {
    console.log(`grep process exited with code ${code}`)
  }
})
js
import { spawn } from 'node:child_process'
const ps = spawn('ps', ['ax'])
const grep = spawn('grep', ['ssh'])

ps.stdout.on('data', data => {
  grep.stdin.write(data)
})

ps.stderr.on('data', data => {
  console.error(`ps stderr: ${data}`)
})

ps.on('close', code => {
  if (code !== 0) {
    console.log(`ps process exited with code ${code}`)
  }
  grep.stdin.end()
})

grep.stdout.on('data', data => {
  console.log(data.toString())
})

grep.stderr.on('data', data => {
  console.error(`grep stderr: ${data}`)
})

grep.on('close', code => {
  if (code !== 0) {
    console.log(`grep process exited with code ${code}`)
  }
})

Exemplo de verificação de spawn falhado:

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

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

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

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:

js
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
js
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:

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

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore',
})

subprocess.unref()
js
import { spawn } from 'node:child_process'
import process from 'node:process'

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore',
})

subprocess.unref()

Alternativamente, pode-se redirecionar a saída do processo filho para arquivos:

js
const { openSync } = require('node:fs')
const { spawn } = require('node:child_process')
const out = openSync('./out.log', 'a')
const err = openSync('./out.log', 'a')

const subprocess = spawn('prg', [], {
  detached: true,
  stdio: ['ignore', out, err],
})

subprocess.unref()
js
import { openSync } from 'node:fs'
import { spawn } from 'node:child_process'
const out = openSync('./out.log', 'a')
const err = openSync('./out.log', 'a')

const subprocess = spawn('prg', [], {
  detached: true,
  stdio: ['ignore', out, err],
})

subprocess.unref()

options.stdio

[Histórico]

VersãoAlterações
v15.6.0, v14.18.0Adicionada a flag overlapped para stdio.
v3.3.1O valor 0 agora é aceito como um descritor de arquivo.
v0.7.10Adicionado 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:

js
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'] })
js
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ãoMudanças
v16.4.0, v14.18.0A opção cwd pode ser um objeto URL WHATWG usando o protocolo file:.
v10.10.0A opção input agora pode ser qualquer TypedArray ou DataView.
v8.8.0A opção windowsHide agora é suportada.
v8.0.0A opção input agora pode ser um Uint8Array.
v6.2.1, v4.5.0A opção encoding agora pode ser explicitamente definida como buffer.
v0.11.12Adicionado 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. Se stdio[0] estiver definido como 'pipe', fornecer este valor substituirá stdio[0].
    • stdio <string> | <Array> Configuração stdio do filho. Consulte o stdio de child_process.spawn(). stderr por padrão será enviado para o stderr do processo pai, a menos que stdio 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 (consulte setuid(2)).
    • gid <number> Define a identidade do grupo do processo (consulte setgid(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 em maxBuffer 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> Se true, executa command dentro de um shell. Usa '/bin/sh' no Unix e process.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).
  • Retorna: <Buffer> | <string> O stdout do comando.

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.

js
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 })
  }
}
js
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ãoMudanças
v16.4.0, v14.18.0A opção cwd pode ser um objeto URL WHATWG usando o protocolo file:.
v10.10.0A opção input agora pode ser qualquer TypedArray ou um DataView.
v8.8.0A opção windowsHide agora é suportada.
v8.0.0A opção input agora pode ser um Uint8Array.
v0.11.12Adicionado 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. Se stdio[0] estiver definido como 'pipe', fornecer esse valor substituirá stdio[0].
    • stdio <string> | <Array> Configuração stdio do filho. Veja child_process.spawn()'s stdio. stderr por padrão será direcionado para o stderr do processo pai, a menos que stdio 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. (Veja setuid(2)).
    • gid <number> Define a identidade do grupo do processo. (Veja setgid(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 em maxBuffer 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.
  • Retorna: <Buffer> | <string> O stdout do comando.

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ãoMudanças
v16.4.0, v14.18.0A opção cwd pode ser um objeto WHATWG URL usando o protocolo file:.
v10.10.0A opção input agora pode ser qualquer TypedArray ou um DataView.
v8.8.0A opção windowsHide agora é suportada.
v8.0.0A opção input agora pode ser um Uint8Array.
v5.7.0A opção shell agora é suportada.
v6.2.1, v4.5.0A opção encoding agora pode ser explicitamente definida como buffer.
v0.11.12Adicionado 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. Se stdio[0] estiver definido como 'pipe', fornecer este valor substituirá stdio[0].
    • argv0 <string> Define explicitamente o valor de argv[0] enviado ao processo filho. Isso será definido como command se não for especificado.
    • stdio <string> | <Array> Configuração stdio do filho. Veja child_process.spawn()'s stdio. 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 (veja setuid(2)).
    • gid <number> Define a identidade do grupo do processo (veja setgid(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 em maxBuffer 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> Se true, executa command dentro de um shell. Usa '/bin/sh' no Unix e process.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 como true automaticamente quando shell é 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 de output[1].
    • stderr <Buffer> | <string> O conteúdo de output[2].
    • status <number> | <null> O código de saída do subprocesso, ou null se o subprocesso foi encerrado devido a um sinal.
    • signal <string> | <null> O sinal usado para encerrar o subprocesso, ou null 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

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.

js
const { spawn } = require('node:child_process')
const ls = spawn('ls', ['-lh', '/usr'])

ls.stdout.on('data', data => {
  console.log(`stdout: ${data}`)
})

ls.on('close', code => {
  console.log(`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}`)
})
js
import { spawn } from 'node:child_process'
const ls = spawn('ls', ['-lh', '/usr'])

ls.stdout.on('data', data => {
  console.log(`stdout: ${data}`)
})

ls.on('close', code => {
  console.log(`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'

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

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ãoAlterações
v14.0.0O objeto não expõe mais acidentalmente ligações nativas C++.
v7.1.0Adicionado 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ós subprocess.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.

js
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')
js
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:

js
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)
js
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 que subprocess.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.

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

console.log(`PID do filho gerado: ${grep.pid}`)
grep.stdin.end()
js
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.

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

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore',
})

subprocess.unref()
subprocess.ref()
js
import { spawn } from 'node:child_process'
import process from 'node:process'

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore',
})

subprocess.unref()
subprocess.ref()

subprocess.send(message[, sendHandle[, options]][, callback])

[Histórico]

VersãoMudanças
v5.8.0O parâmetro options, e a opção keepOpen em particular, são suportados agora.
v5.0.0Este método agora retorna um booleano para controle de fluxo.
v4.0.0O parâmetro callback agora é suportado.
v0.5.9Adicionado em: v0.5.9
  • message <Object>

  • sendHandle <Handle> | <undefined> undefined, ou um objeto net.Socket, net.Server, ou dgram.Socket.

  • options <Object> O argumento options, 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 de net.Socket. Quando true, 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:

js
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' })
js
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:

js
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:

js
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)
})
js
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:

js
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":

js
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)
js
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:

js
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.

js
const assert = require('node:assert')
const fs = require('node:fs')
const child_process = require('node:child_process')

const subprocess = child_process.spawn('ls', {
  stdio: [
    0, // Use 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)
js
import assert from 'node:assert'
import fs from 'node:fs'
import child_process from 'node:child_process'

const subprocess = child_process.spawn('ls', {
  stdio: [
    0, // Use 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.

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

const subprocess = spawn('ls')

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

const subprocess = spawn('ls')

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

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.

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

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore',
})

subprocess.unref()
js
import { spawn } from 'node:child_process'
import process from 'node:process'

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore',
})

subprocess.unref()

maxBuffer 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().