Skip to content

子プロセス

[Stable: 2 - 安定版]

Stable: 2 安定度: 2 - 安定版

ソースコード: lib/child_process.js

node:child_process モジュールは、popen(3) と同様の方法で(ただし同一ではない)、サブプロセスを生成する機能を提供します。この機能は主に 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(`子プロセスはコード ${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(`子プロセスはコード ${code} で終了しました`)
})

デフォルトでは、stdinstdout、および stderr のパイプが、親の Node.js プロセスと生成されたサブプロセスの間に確立されます。これらのパイプには、制限された(プラットフォーム固有の)容量があります。サブプロセスがキャプチャされずにその制限を超える量を stdout に書き込むと、サブプロセスはパイプバッファがより多くのデータを受け入れるのを待機してブロックします。これは、シェルでのパイプの動作と同じです。出力が消費されない場合は、{ stdio: 'ignore' } オプションを使用してください。

コマンド検索は、options オブジェクトに env が含まれている場合は options.env.PATH 環境変数を使用して実行されます。それ以外の場合は、process.env.PATH が使用されます。 options.envPATH なしで設定されている場合、Unix では /usr/bin:/bin のデフォルトの検索パス(execvpe/execvp についてはオペレーティングシステムのマニュアルを参照してください)で検索が実行され、Windows では現在のプロセスの環境変数 PATH が使用されます。

Windows では、環境変数は大文字と小文字を区別しません。Node.js は env キーを辞書式順にソートし、大文字と小文字を区別せずに一致する最初のものを使用します。最初の(辞書順で)エントリのみがサブプロセスに渡されます。これにより、PATHPath など、同じキーの複数のバリアントを持つオブジェクトを env オプションに渡すときに、Windows で問題が発生する可能性があります。

child_process.spawn() メソッドは、Node.js イベントループをブロックせずに、子プロセスを非同期的に生成します。child_process.spawnSync() 関数は、生成されたプロセスが終了または終了するまでイベントループをブロックする同期的な方法で同等の機能を提供します。

便宜上、node:child_process モジュールは、child_process.spawn() および child_process.spawnSync() の同期および非同期の代替手段をいくつか提供しています。これらの代替手段はそれぞれ、child_process.spawn() または child_process.spawnSync() の上に実装されています。

シェルスクリプトの自動化など、特定のユースケースでは、同期カウンターパート がより便利な場合があります。しかし多くの場合、同期メソッドは、生成されたプロセスの完了中にイベントループを停止させるため、パフォーマンスに大きな影響を与える可能性があります。

非同期プロセス生成

child_process.spawn()child_process.fork()child_process.exec()、および child_process.execFile() メソッドはすべて、他の Node.js API に典型的な慣用的な非同期プログラミングパターンに従います。

各メソッドは、ChildProcess インスタンスを返します。これらのオブジェクトは、Node.js の EventEmitter API を実装しており、親プロセスが子プロセスのライフサイクル中に特定のイベントが発生したときに呼び出されるリスナー関数を登録できます。

child_process.exec() および child_process.execFile() メソッドでは、子プロセスが終了したときに呼び出されるオプションの callback 関数を指定することもできます。

Windows での .bat および .cmd ファイルの生成

child_process.exec()child_process.execFile() の区別の重要性は、プラットフォームによって異なる場合があります。Unix タイプのオペレーティングシステム (Unix、Linux、macOS) では、child_process.execFile() はデフォルトでシェルを生成しないため、より効率的です。ただし、Windows では、.bat および .cmd ファイルはターミナルなしでは単独で実行できないため、child_process.execFile() を使用して起動することはできません。Windows で実行する場合、.bat および .cmd ファイルは、shell オプションを設定した child_process.spawn()child_process.exec() を使用するか、cmd.exe を生成して .bat または .cmd ファイルを引数として渡すことで呼び出すことができます(これが shell オプションと child_process.exec() が行っていることです)。いずれの場合も、スクリプトのファイル名にスペースが含まれている場合は、引用符で囲む必要があります。

js
// OR...
const { exec, spawn } = require('node:child_process')

exec('my.bat', (err, stdout, stderr) => {
  if (err) {
    console.error(err)
    return
  }
  console.log(stdout)
})

// ファイル名にスペースが含まれるスクリプト:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true })
// or:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
  // ...
})
js
// OR...
import { exec, spawn } from 'node:child_process'

exec('my.bat', (err, stdout, stderr) => {
  if (err) {
    console.error(err)
    return
  }
  console.log(stdout)
})

// ファイル名にスペースが含まれるスクリプト:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true })
// or:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
  // ...
})

child_process.exec(command[, options][, callback])

[履歴]

バージョン変更点
v15.4.0AbortSignal のサポートが追加されました。
v16.4.0, v14.18.0cwd オプションは file: プロトコルを使用する WHATWG URL オブジェクトにできます。
v8.8.0windowsHide オプションがサポートされるようになりました。
v0.1.90v0.1.90 で追加されました。
  • command <string> 実行するコマンド。引数はスペースで区切ります。

  • options <Object>

    • cwd <string> | <URL> 子プロセスの現在の作業ディレクトリ。デフォルト: process.cwd()
    • env <Object> 環境キーと値のペア。デフォルト: process.env
    • encoding <string> デフォルト: 'utf8'
    • shell <string> コマンドを実行するシェル。シェルの要件 および Windows のデフォルトシェル を参照してください。デフォルト: Unix では '/bin/sh'、Windows では process.env.ComSpec
    • signal <AbortSignal> AbortSignal を使用して子プロセスを中止できるようにします。
    • timeout <number> デフォルト: 0
    • maxBuffer <number> stdout または stderr で許容されるデータの最大量(バイト単位)。これを超えると、子プロセスは終了し、出力は切り捨てられます。maxBuffer および Unicode での注意点を確認してください。 デフォルト: 1024 * 1024
    • killSignal <string> | <integer> デフォルト: 'SIGTERM'
    • uid <number> プロセスのユーザー ID を設定します(setuid(2) を参照)。
    • gid <number> プロセスのグループ ID を設定します(setgid(2) を参照)。
    • windowsHide <boolean> 通常 Windows システムで作成されるサブプロセスコンソールウィンドウを非表示にします。 デフォルト: false
  • callback <Function> プロセスが終了したときに出力とともに呼び出されます。

  • 戻り値: <ChildProcess>

シェルを起動し、そのシェル内で command を実行して、生成された出力をバッファリングします。exec 関数に渡される command 文字列はシェルによって直接処理され、特殊文字(シェル によって異なります)は適切に処理する必要があります。

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

exec('"/path/to/test file/test.sh" arg1 arg2')
// パス内のスペースが複数の引数の区切り文字として解釈されないように、二重引用符を使用します。

exec('echo "The \\$HOME variable is $HOME"')
// $HOME 変数は、最初のインスタンスではエスケープされますが、2 番目のインスタンスではエスケープされません。
js
import { exec } from 'node:child_process'

exec('"/path/to/test file/test.sh" arg1 arg2')
// パス内のスペースが複数の引数の区切り文字として解釈されないように、二重引用符を使用します。

exec('echo "The \\$HOME variable is $HOME"')
// $HOME 変数は、最初のインスタンスではエスケープされますが、2 番目のインスタンスではエスケープされません。

この関数には、サニタイズされていないユーザー入力を絶対に渡さないでください。シェル メタ文字を含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。

callback 関数が指定されている場合は、引数 (error, stdout, stderr) を使用して呼び出されます。成功した場合、errornull になります。エラーが発生した場合、errorError のインスタンスになります。error.code プロパティは、プロセスの終了コードになります。慣例により、0 以外の終了コードはエラーを示します。error.signal は、プロセスを終了したシグナルになります。

コールバックに渡される stdout および stderr 引数には、子プロセスの stdout および stderr 出力が含まれます。デフォルトでは、Node.js は出力を UTF-8 としてデコードし、文字列をコールバックに渡します。encoding オプションを使用して、stdout および stderr 出力のデコードに使用する文字エンコーディングを指定できます。encoding'buffer' または認識されない文字エンコーディングである場合、代わりに Buffer オブジェクトがコールバックに渡されます。

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

timeout0 より大きい場合、子プロセスが timeout ミリ秒より長く実行されると、親プロセスは killSignal プロパティで識別されるシグナル(デフォルトは 'SIGTERM')を送信します。

exec(3) POSIX システムコールとは異なり、child_process.exec() は既存のプロセスを置き換えず、シェルを使用してコマンドを実行します。

このメソッドが util.promisify()ed バージョンとして呼び出された場合、stdout および stderr プロパティを持つ ObjectPromise を返します。返された ChildProcess インスタンスは、child プロパティとして Promise にアタッチされます。エラー(0 以外の終了コードになるエラーを含む)が発生した場合、コールバックで指定されたものと同じ error オブジェクトで拒否されたプロミスが返されますが、追加のプロパティ stdout および stderr が付いています。

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

signal オプションが有効になっている場合、対応する AbortController.abort() を呼び出すことは、子プロセスで .kill() を呼び出すことと似ていますが、コールバックに渡されるエラーは 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) // an 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) // an AbortError
})
controller.abort()

child_process.execFile(file[, args][, options][, callback])

[履歴]

バージョン変更点
v16.4.0, v14.18.0cwd オプションは、file: プロトコルを使用する WHATWG URL オブジェクトにすることができます。
v15.4.0, v14.17.0AbortSignal のサポートが追加されました。
v8.8.0windowsHide オプションがサポートされるようになりました。
v0.1.91v0.1.91 で追加されました。
  • file <string> 実行する実行可能ファイルの名前またはパス。

  • args <string[]> 文字列引数のリスト。

  • options <Object>

    • cwd <string> | <URL> 子プロセスの現在の作業ディレクトリ。
    • env <Object> 環境キーと値のペア。デフォルト: process.env
    • encoding <string> デフォルト: 'utf8'
    • timeout <number> デフォルト: 0
    • maxBuffer <number> stdout または stderr で許可される最大データ量(バイト単位)。これを超えると、子プロセスは終了し、出力は切り捨てられます。maxBuffer と Unicode の注意点をご覧ください。デフォルト: 1024 * 1024
    • killSignal <string> | <integer> デフォルト: 'SIGTERM'
    • uid <number> プロセスのユーザー ID を設定します (setuid(2) を参照)。
    • gid <number> プロセスのグループ ID を設定します (setgid(2) を参照)。
    • windowsHide <boolean> 通常 Windows システムで作成されるサブプロセスのコンソールウィンドウを非表示にします。デフォルト: false
    • windowsVerbatimArguments <boolean> Windows では引数のクォートやエスケープは行われません。Unix では無視されます。デフォルト: false
    • shell <boolean> | <string> true の場合、シェル内で command を実行します。Unix では '/bin/sh'、Windows では process.env.ComSpec を使用します。異なるシェルを文字列として指定できます。シェルの要件 および デフォルトの Windows シェル を参照してください。デフォルト: false (シェルなし)。
    • signal <AbortSignal> AbortSignal を使用して子プロセスを中断できるようにします。
  • callback <Function> プロセスが終了したときに出力とともに呼び出されます。

  • 戻り値: <ChildProcess>

child_process.execFile() 関数は、デフォルトでシェルを起動しない点を除いて、child_process.exec() と似ています。代わりに、指定された実行可能ファイル file が新しいプロセスとして直接起動されるため、child_process.exec() よりもわずかに効率的です。

child_process.exec() と同じオプションがサポートされています。シェルが起動されないため、I/O リダイレクトやファイル グロビングなどの動作はサポートされていません。

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

コールバックに渡される stdout および stderr 引数には、子プロセスの stdout および stderr 出力が含まれます。デフォルトでは、Node.js は出力を UTF-8 としてデコードし、文字列をコールバックに渡します。encoding オプションを使用して、stdout および stderr 出力のデコードに使用される文字エンコーディングを指定できます。encoding'buffer' であるか、認識されない文字エンコーディングの場合、代わりに Buffer オブジェクトがコールバックに渡されます。

このメソッドが util.promisify()化されたバージョンとして呼び出された場合、stdout および stderr プロパティを持つ ObjectPromise を返します。返された ChildProcess インスタンスは、Promisechild プロパティとしてアタッチされます。エラーが発生した場合 (0 以外の終了コードを招くエラーを含む)、拒否された Promise が返され、コールバックで指定されたのと同じ error オブジェクトが返されますが、2 つの追加プロパティ stdout および 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()

shell オプションが有効になっている場合は、サニタイズされていないユーザー入力をこの関数に渡さないでください。シェル メタキャラクターを含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。

signal オプションが有効になっている場合、対応する AbortController.abort() を呼び出すことは、子プロセスで .kill() を呼び出すのと似ていますが、コールバックに渡されるエラーは 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) // an 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) // an AbortError
})
controller.abort()

child_process.fork(modulePath[, args][, options])

[履歴]

バージョン変更点
v17.4.0, v16.14.0modulePath パラメーターは、file: プロトコルを使用する WHATWG URL オブジェクトにできます。
v16.4.0, v14.18.0cwd オプションは、file: プロトコルを使用する WHATWG URL オブジェクトにできます。
v15.13.0, v14.18.0timeout が追加されました。
v15.11.0, v14.18.0AbortSignal の killSignal が追加されました。
v15.6.0, v14.17.0AbortSignal のサポートが追加されました。
v13.2.0, v12.16.0serialization オプションがサポートされるようになりました。
v8.0.0stdio オプションは文字列にできるようになりました。
v6.4.0stdio オプションがサポートされるようになりました。
v0.5.0追加: v0.5.0
  • modulePath <string> | <URL> 子プロセスで実行するモジュール。

  • args <string[]> 文字列引数のリスト。

  • options <Object>

    • cwd <string> | <URL> 子プロセスの現在の作業ディレクトリ。
    • detached <boolean> 親プロセスから独立して実行するために子プロセスを準備します。具体的な動作はプラットフォームに依存します。options.detached を参照してください。
    • env <Object> 環境キーと値のペア。デフォルト: process.env
    • execPath <string> 子プロセスの作成に使用される実行可能ファイル。
    • execArgv <string[]> 実行可能ファイルに渡される文字列引数のリスト。デフォルト: process.execArgv
    • gid <number> プロセスのグループ ID を設定します (setgid(2) を参照)。
    • serialization <string> プロセス間でメッセージを送信するために使用されるシリアライズの種類を指定します。可能な値は 'json''advanced' です。詳細は 高度なシリアライズ を参照してください。デフォルト: 'json'
    • signal <AbortSignal> AbortSignal を使用して子プロセスを閉じることができます。
    • killSignal <string> | <integer> タイムアウトまたは中止シグナルによってスポーンされたプロセスが強制終了されるときに使用されるシグナル値。デフォルト: 'SIGTERM'
    • silent <boolean> true の場合、子プロセスの stdin、stdout、stderr は親プロセスにパイプされます。そうでない場合は、親プロセスから継承されます。詳細は child_process.spawn()'s の stdio'pipe' および 'inherit' オプションを参照してください。デフォルト: false
    • stdio <Array> | <string> child_process.spawn()'s の stdio を参照してください。このオプションが指定されている場合、silent をオーバーライドします。配列形式を使用する場合、値 'ipc' を持つ項目を 1 つだけ含める必要があり、そうでない場合はエラーがスローされます。たとえば、[0, 1, 2, 'ipc'] のようにします。
    • uid <number> プロセスのユーザー ID を設定します (setuid(2) を参照)。
    • windowsVerbatimArguments <boolean> Windows では引数の引用符やエスケープ処理は行われません。Unix では無視されます。デフォルト: false
    • timeout <number> プロセスの実行が許可される最大時間(ミリ秒単位)。デフォルト: undefined
  • 戻り値: <ChildProcess>

child_process.fork() メソッドは、新しい Node.js プロセスを生成するために特別に使用される child_process.spawn() の特殊なケースです。child_process.spawn() と同様に、ChildProcess オブジェクトが返されます。返される ChildProcess には、親と子でメッセージをやり取りできる組み込みの追加通信チャネルがあります。詳細は subprocess.send() を参照してください。

生成された Node.js 子プロセスは、2 つの間で確立される IPC 通信チャネルを除いて、親から独立していることに注意してください。各プロセスには独自のメモリがあり、独自の V8 インスタンスがあります。必要な追加のリソース割り当てのため、多数の Node.js 子プロセスを生成することは推奨されません。

デフォルトでは、child_process.fork() は親プロセスの process.execPath を使用して新しい Node.js インスタンスを生成します。options オブジェクトの execPath プロパティを使用すると、代替の実行パスを使用できます。

カスタム execPath で起動された Node.js プロセスは、子プロセスの環境変数 NODE_CHANNEL_FD を使用して識別されるファイル記述子(fd)を使用して親プロセスと通信します。

fork(2) POSIX システムコールとは異なり、child_process.fork() は現在のプロセスをクローンしません。

child_process.spawn() で利用可能な shell オプションは child_process.fork() ではサポートされておらず、設定しても無視されます。

signal オプションが有効になっている場合、対応する AbortController.abort() を呼び出すことは、子プロセスで .kill() を呼び出すのと同様ですが、コールバックに渡されるエラーは AbortError になります。

js
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 => {
    // これは、コントローラーが中止された場合、err が AbortError である状態で呼び出されます
  })
  controller.abort() // 子プロセスを停止します
}
js
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 => {
    // これは、コントローラーが中止された場合、err が AbortError である状態で呼び出されます
  })
  controller.abort() // 子プロセスを停止します
}

child_process.spawn(command[, args][, options])

[History]

バージョン変更点
v16.4.0, v14.18.0cwd オプションに file: プロトコルを使用する WHATWG URL オブジェクトを指定できるようになりました。
v15.13.0, v14.18.0timeout が追加されました。
v15.11.0, v14.18.0AbortSignal の killSignal が追加されました。
v15.5.0, v14.17.0AbortSignal のサポートが追加されました。
v13.2.0, v12.16.0serialization オプションがサポートされるようになりました。
v8.8.0windowsHide オプションがサポートされるようになりました。
v6.4.0argv0 オプションがサポートされるようになりました。
v5.7.0shell オプションがサポートされるようになりました。
v0.1.90追加: v0.1.90
  • command <string> 実行するコマンド。

  • args <string[]> 文字列引数のリスト。

  • options <Object>

    • cwd <string> | <URL> 子プロセスの現在のワーキングディレクトリ。
    • env <Object> 環境変数のキーと値のペア。デフォルト: process.env
    • argv0 <string> 子プロセスに送信される argv[0] の値を明示的に設定します。指定しない場合は、command に設定されます。
    • stdio <Array> | <string> 子の stdio 構成 (options.stdio を参照)。
    • detached <boolean> 子プロセスを親プロセスから独立して実行するように準備します。具体的な動作はプラットフォームによって異なります (options.detached を参照)。
    • uid <number> プロセスのユーザー ID を設定します (setuid(2) を参照)。
    • gid <number> プロセスのグループ ID を設定します (setgid(2) を参照)。
    • serialization <string> プロセス間でメッセージを送信するために使用されるシリアライズの種類を指定します。可能な値は 'json''advanced' です。詳細については、高度なシリアライズ を参照してください。デフォルト: 'json'
    • shell <boolean> | <string> true の場合、シェル内で command を実行します。Unix では '/bin/sh' を使用し、Windows では process.env.ComSpec を使用します。文字列として別のシェルを指定できます。シェルの要件 および Windows のデフォルトシェル を参照してください。デフォルト: false (シェルなし)。
    • windowsVerbatimArguments <boolean> Windows では引数の引用符やエスケープは行われません。Unix では無視されます。これは shell が指定され、CMD の場合は自動的に true に設定されます。デフォルト: false
    • windowsHide <boolean> 通常 Windows システムで作成されるサブプロセスのコンソールウィンドウを非表示にします。デフォルト: false
    • signal <AbortSignal> AbortSignal を使用して子プロセスを中止できるようにします。
    • timeout <number> プロセスの実行が許可される最大時間(ミリ秒単位)。デフォルト: undefined
    • killSignal <string> | <integer> タイムアウトまたは中止シグナルによって生成されたプロセスが強制終了される場合に使用されるシグナル値。デフォルト: 'SIGTERM'
  • 戻り値: <ChildProcess>

child_process.spawn() メソッドは、指定された command を使用して新しいプロセスを生成し、args にコマンドライン引数を指定します。省略した場合、args のデフォルトは空の配列です。

shell オプションが有効になっている場合、この関数にサニタイズされていないユーザー入力を渡さないでください。シェルメタ文字を含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。

3 番目の引数を使用して追加のオプションを指定できます。これらのデフォルトは次のとおりです。

js
const defaults = {
  cwd: undefined,
  env: process.env,
}

cwd を使用して、プロセスが生成されるワーキングディレクトリを指定します。指定しない場合、デフォルトは現在のワーキングディレクトリを継承します。指定した場合でも、パスが存在しない場合は、子プロセスは ENOENT エラーを発行してすぐに終了します。ENOENT はコマンドが存在しない場合にも発行されます。

env を使用して、新しいプロセスに表示される環境変数を指定します。デフォルトは process.env です。

envundefined 値は無視されます。

ls -lh /usr を実行し、stdoutstderr、および終了コードをキャプチャする例:

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

例: 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}`)
  }
})

spawn が失敗した場合の確認例:

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.')
})

特定のプラットフォーム (macOS、Linux) ではプロセスのタイトルに argv[0] の値が使用され、他のプラットフォーム (Windows、SunOS) では command が使用されます。

Node.js は起動時に argv[0]process.execPath で上書きするため、Node.js の子プロセスの process.argv[0] は、親から spawn に渡された argv0 パラメータと一致しません。代わりに process.argv0 プロパティで取得します。

signal オプションが有効になっている場合、対応する AbortController.abort() を呼び出すことは、子プロセスで .kill() を呼び出すことと似ていますが、コールバックに渡されるエラーは 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 => {
  // コントローラーが中止された場合、これは AbortError である err で呼び出されます
})
controller.abort() // 子プロセスを停止します
js
import { spawn } from 'node:child_process'
const controller = new AbortController()
const { signal } = controller
const grep = spawn('grep', ['ssh'], { signal })
grep.on('error', err => {
  // コントローラーが中止された場合、これは AbortError である err で呼び出されます
})
controller.abort() // 子プロセスを停止します

options.detached

追加: v0.7.10

Windows では、options.detachedtrueに設定すると、親プロセスが終了した後も子プロセスが実行を継続できるようになります。子プロセスは独自のコンソールウィンドウを持つようになります。子プロセスで有効にすると、無効にすることはできません。

Windows 以外のプラットフォームでは、options.detachedtrueに設定されている場合、子プロセスは新しいプロセスグループとセッションのリーダーになります。子プロセスは、デタッチされているかどうかに関係なく、親プロセスが終了した後も実行を継続できます。詳細についてはsetsid(2)を参照してください。

デフォルトでは、親プロセスはデタッチされた子プロセスが終了するのを待ちます。親プロセスが特定のsubprocessの終了を待機しないようにするには、subprocess.unref()メソッドを使用します。これにより、親プロセスのイベントループが子プロセスを参照カウントに含めなくなり、子プロセスと親プロセスの間に確立された IPC チャネルがない限り、親プロセスは子プロセスとは独立して終了できます。

detachedオプションを使用して長時間実行されるプロセスを開始する場合、プロセスが親に接続されていないstdio構成が提供されない限り、親が終了した後もバックグラウンドで実行されません。親プロセスのstdioが継承された場合、子プロセスは制御端末に接続されたままになります。

親の終了を無視するために、デタッチして親のstdioファイルディスクリプタを無視することによる長時間実行プロセスの例:

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

あるいは、子プロセスの出力をファイルにリダイレクトすることもできます。

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

[履歴]

バージョン変更点
v15.6.0, v14.18.0overlapped stdio フラグが追加されました。
v3.3.10 がファイル記述子として受け入れられるようになりました。
v0.7.10追加: v0.7.10

options.stdio オプションは、親プロセスと子プロセスの間に確立されるパイプを設定するために使用されます。デフォルトでは、子プロセスの stdin、stdout、および stderr は、ChildProcess オブジェクト上の対応する subprocess.stdinsubprocess.stdout、および subprocess.stderr ストリームにリダイレクトされます。これは、options.stdio['pipe', 'pipe', 'pipe'] に設定するのと同じです。

便宜上、options.stdio は次のいずれかの文字列にすることができます。

  • 'pipe': ['pipe', 'pipe', 'pipe'] と同等 (デフォルト)
  • 'overlapped': ['overlapped', 'overlapped', 'overlapped'] と同等
  • 'ignore': ['ignore', 'ignore', 'ignore'] と同等
  • 'inherit': ['inherit', 'inherit', 'inherit'] または [0, 1, 2] と同等

それ以外の場合、options.stdio の値は配列であり、各インデックスは子プロセスの fd に対応します。fd の 0、1、および 2 は、それぞれ stdin、stdout、および stderr に対応します。追加の fd を指定して、親と子の間に追加のパイプを作成できます。値は次のいずれかになります。

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

// 子は親の stdio を使用します。
spawn('prg', [], { stdio: 'inherit' })

// stderr のみを共有する子を生成します。
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] })

// startd スタイルのインターフェースを提供するプログラムとやり取りするための、
// 追加の fd=4 を開きます。
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] })
js
import { spawn } from 'node:child_process'
import process from 'node:process'

// 子は親の stdio を使用します。
spawn('prg', [], { stdio: 'inherit' })

// stderr のみを共有する子を生成します。
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] })

// startd スタイルのインターフェースを提供するプログラムとやり取りするための、
// 追加の fd=4 を開きます。
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] })

親プロセスと子プロセスの間に IPC チャネルが確立され、子プロセスが Node.js インスタンスである場合、子プロセスは、子プロセスが 'disconnect' イベントまたは 'message' イベントのイベント ハンドラーを登録するまで、IPC チャネルが参照解除された状態 (unref() を使用) で起動されることに注意してください。これにより、開いている IPC チャネルによってプロセスが開いたままになることなく、子プロセスが正常に終了できます。 参照: child_process.exec() および child_process.fork()

同期的なプロセス生成

child_process.spawnSync()child_process.execSync()、およびchild_process.execFileSync() メソッドは同期的であり、Node.js イベントループをブロックし、スポーンされたプロセスが終了するまで追加のコードの実行を一時停止します。

このようなブロッキング呼び出しは、主に汎用的なスクリプト処理タスクを簡略化したり、起動時のアプリケーション設定の読み込み/処理を簡略化したりするのに役立ちます。

child_process.execFileSync(file[, args][, options])

[履歴]

バージョン変更点
v16.4.0, v14.18.0cwd オプションは、file: プロトコルを使用する WHATWG URL オブジェクトにできます。
v10.10.0input オプションは、任意の TypedArray または DataView にできるようになりました。
v8.8.0windowsHide オプションがサポートされるようになりました。
v8.0.0input オプションは、Uint8Array にできるようになりました。
v6.2.1, v4.5.0encoding オプションは、明示的に buffer に設定できるようになりました。
v0.11.12追加: v0.11.12
  • file <string> 実行する実行可能ファイルの名前またはパス。

  • args <string[]> 文字列引数のリスト。

  • options <Object>

    • cwd <string> | <URL> 子プロセスの現在の作業ディレクトリ。
    • input <string> | <Buffer> | <TypedArray> | <DataView> スポーンされたプロセスに stdin として渡される値。stdio[0]'pipe' に設定されている場合、この値を指定すると stdio[0] が上書きされます。
    • stdio <string> | <Array> 子の stdio 構成。child_process.spawn()stdio を参照してください。 stdio が指定されていない限り、デフォルトでは stderr は親プロセスの stderr に出力されます。デフォルト: 'pipe'
    • env <Object> 環境のキーと値のペア。デフォルト: process.env
    • uid <number> プロセスのユーザー ID を設定します (setuid(2) を参照)。
    • gid <number> プロセスのグループ ID を設定します (setgid(2) を参照)。
    • timeout <number> プロセスの実行が許可される最大時間(ミリ秒単位)。デフォルト: undefined
    • killSignal <string> | <integer> スポーンされたプロセスが強制終了されるときに使用されるシグナル値。デフォルト: 'SIGTERM'
    • maxBuffer <number> stdout または stderr で許可される最大のデータ量(バイト単位)。これを超えると、子プロセスは終了します。maxBuffer と Unicode の注意点をご覧ください。デフォルト: 1024 * 1024
    • encoding <string> すべての stdio 入出力に使用されるエンコーディング。デフォルト: 'buffer'
    • windowsHide <boolean> 通常 Windows システムで作成されるサブプロセスのコンソール ウィンドウを非表示にします。デフォルト: false
    • shell <boolean> | <string> true の場合、シェル内で command を実行します。Unix では '/bin/sh' を使用し、Windows では process.env.ComSpec を使用します。別のシェルを文字列として指定できます。シェルの要件Windows のデフォルト シェルを参照してください。デフォルト: false (シェルなし)。
  • 戻り値: <Buffer> | <string> コマンドからの stdout。

child_process.execFileSync() メソッドは、一般的に child_process.execFile() と同一ですが、子プロセスが完全に終了するまでメソッドが戻らないという例外があります。タイムアウトが発生し、killSignal が送信された場合、プロセスが完全に終了するまでメソッドは戻りません。

子プロセスが SIGTERM シグナルをインターセプトして処理し、終了しない場合でも、親プロセスは子プロセスが終了するまで待機します。

プロセスがタイムアウトするか、ゼロ以外の終了コードを持つ場合、このメソッドは、基盤となる child_process.spawnSync() の完全な結果を含む Error をスローします。

shell オプションが有効になっている場合は、この関数にサニタイズされていないユーザー入力を渡さないでください。シェル メタキャラクターを含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。

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

try {
  const stdout = execFileSync('my-script.sh', ['my-arg'], {
    // 子プロセスからの stdout および stderr をキャプチャします。
    // デフォルトの動作である子 stderr を親 stderr にストリーミングする動作を上書きします。
    stdio: 'pipe',

    // stdio パイプに utf8 エンコーディングを使用します。
    encoding: 'utf8',
  })

  console.log(stdout)
} catch (err) {
  if (err.code) {
    // 子プロセスの生成に失敗しました。
    console.error(err.code)
  } else {
    // 子プロセスは生成されたが、ゼロ以外の終了コードで終了しました。
    // エラーには子プロセスからの stdout および stderr が含まれています。
    const { stdout, stderr } = err

    console.error({ stdout, stderr })
  }
}
js
import { execFileSync } from 'node:child_process'

try {
  const stdout = execFileSync('my-script.sh', ['my-arg'], {
    // 子プロセスからの stdout および stderr をキャプチャします。
    // デフォルトの動作である子 stderr を親 stderr にストリーミングする動作を上書きします。
    stdio: 'pipe',

    // stdio パイプに utf8 エンコーディングを使用します。
    encoding: 'utf8',
  })

  console.log(stdout)
} catch (err) {
  if (err.code) {
    // 子プロセスの生成に失敗しました。
    console.error(err.code)
  } else {
    // 子プロセスは生成されたが、ゼロ以外の終了コードで終了しました。
    // エラーには子プロセスからの stdout および stderr が含まれています。
    const { stdout, stderr } = err

    console.error({ stdout, stderr })
  }
}

child_process.execSync(command[, options])

[履歴]

バージョン変更点
v16.4.0, v14.18.0cwdオプションは、file:プロトコルを使用する WHATWG URLオブジェクトにすることができます。
v10.10.0inputオプションは、任意のTypedArrayまたはDataViewにすることができます。
v8.8.0windowsHideオプションがサポートされました。
v8.0.0inputオプションは、Uint8Arrayにすることができます。
v0.11.12v0.11.12 で追加されました。
  • command <string> 実行するコマンド。

  • options <Object>

    • cwd <string> | <URL> 子プロセスの現在の作業ディレクトリ。
    • input <string> | <Buffer> | <TypedArray> | <DataView> スポーンされたプロセスに stdin として渡される値。 stdio[0]'pipe'に設定されている場合、この値を指定するとstdio[0]がオーバーライドされます。
    • stdio <string> | <Array> 子プロセスの stdio 構成。 child_process.spawn()stdio を参照してください。 stdioが指定されていない限り、stderrはデフォルトで親プロセスの stderr に出力されます。 デフォルト: 'pipe'
    • env <Object> 環境キーと値のペア。デフォルト: process.env
    • shell <string> コマンドを実行するシェル。 シェルの要件 および デフォルトの Windows シェル を参照してください。 デフォルト: Unix では'/bin/sh'、Windows ではprocess.env.ComSpec
    • uid <number> プロセスのユーザー ID を設定します。(setuid(2) を参照)。
    • gid <number> プロセスのグループ ID を設定します。(setgid(2) を参照)。
    • timeout <number> プロセスの実行を許可する最大時間(ミリ秒単位)。デフォルト: undefined
    • killSignal <string> | <integer> スポーンされたプロセスを強制終了するときに使用されるシグナル値。デフォルト: 'SIGTERM'
    • maxBuffer <number> stdout または stderr で許可される最大のデータ量(バイト単位)。これを超えると、子プロセスは強制終了され、出力は切り捨てられます。 maxBufferと Unicodeの注意点をご覧ください。デフォルト: 1024 * 1024
    • encoding <string> すべての stdio 入力および出力に使用されるエンコーディング。デフォルト: 'buffer'
    • windowsHide <boolean> 通常 Windows システムで作成されるサブプロセスのコンソールウィンドウを非表示にします。 デフォルト: false
  • 返り値: <Buffer> | <string> コマンドからの stdout。

child_process.execSync()メソッドは、子プロセスが完全に閉じるまでメソッドが返らない点を除いて、一般的にchild_process.exec()と同じです。タイムアウトが発生してkillSignalが送信された場合、メソッドはプロセスが完全に終了するまで返りません。子プロセスがSIGTERMシグナルをインターセプトして処理し、終了しない場合、親プロセスは子プロセスが終了するまで待機します。

プロセスがタイムアウトするか、ゼロ以外の終了コードを持つ場合、このメソッドはエラーをスローします。Errorオブジェクトには、child_process.spawnSync()からの結果全体が含まれます。

サニタイズされていないユーザー入力をこの関数に渡さないでください。シェルメタ文字を含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。

child_process.spawnSync(command[, args][, options])

[履歴]

バージョン変更
v16.4.0, v14.18.0cwd オプションは file: プロトコルを使用する WHATWG URL オブジェクトにすることができます。
v10.10.0input オプションは任意の TypedArray または DataView にできるようになりました。
v8.8.0windowsHide オプションがサポートされるようになりました。
v8.0.0input オプションは Uint8Array にできるようになりました。
v5.7.0shell オプションがサポートされるようになりました。
v6.2.1, v4.5.0encoding オプションは明示的に buffer に設定できるようになりました。
v0.11.12v0.11.12 で追加されました。
  • command <string> 実行するコマンド。

  • args <string[]> 文字列引数のリスト。

  • options <Object>

    • cwd <string> | <URL> 子プロセスの現在のワーキングディレクトリ。
    • input <string> | <Buffer> | <TypedArray> | <DataView> スポーンされたプロセスに stdin として渡される値。stdio[0]'pipe' に設定されている場合、この値を指定すると stdio[0] が上書きされます。
    • argv0 <string> 子プロセスに送信される argv[0] の値を明示的に設定します。指定しない場合、これは command に設定されます。
    • stdio <string> | <Array> 子の stdio 設定。child_process.spawn()stdio を参照してください。デフォルト: 'pipe'
    • env <Object> 環境キーと値のペア。デフォルト: process.env
    • uid <number> プロセスのユーザー ID を設定します(setuid(2) を参照)。
    • gid <number> プロセスのグループ ID を設定します(setgid(2) を参照)。
    • timeout <number> プロセスの実行を許可する最大時間をミリ秒単位で指定します。デフォルト: undefined
    • killSignal <string> | <integer> スポーンされたプロセスを強制終了するときに使用するシグナル値。デフォルト: 'SIGTERM'
    • maxBuffer <number> stdout または stderr で許可される最大データ量(バイト単位)。これを超えると、子プロセスは終了し、出力は切り捨てられます。maxBuffer と Unicode の注意点をご覧ください。デフォルト: 1024 * 1024
    • encoding <string> すべての stdio 入力と出力に使用されるエンコーディング。デフォルト: 'buffer'
    • shell <boolean> | <string> true の場合、command はシェル内で実行されます。Unix では '/bin/sh' を、Windows では process.env.ComSpec を使用します。別のシェルを文字列として指定できます。シェルの要件 および Windows のデフォルトシェル を参照してください。デフォルト: false (シェルなし)。
    • windowsVerbatimArguments <boolean> Windows では引数のクォーティングやエスケープは行われません。Unix では無視されます。これは、shell が指定され、CMD である場合は自動的に true に設定されます。デフォルト: false
    • windowsHide <boolean> 通常 Windows システムで作成されるサブプロセスのコンソールウィンドウを非表示にします。デフォルト: false
  • 戻り値: <Object>

    • pid <number> 子プロセスの PID。
    • output <Array> stdio 出力からの結果の配列。
    • stdout <Buffer> | <string> output[1] の内容。
    • stderr <Buffer> | <string> output[2] の内容。
    • status <number> | <null> サブプロセスの終了コード。シグナルによってサブプロセスが終了した場合は null
    • signal <string> | <null> サブプロセスを強制終了するために使用されたシグナル。サブプロセスがシグナルによって終了しなかった場合は null
    • error <Error> 子プロセスが失敗またはタイムアウトした場合のエラーオブジェクト。

child_process.spawnSync() メソッドは、子プロセスが完全に終了するまで関数が戻らないという点を除いて、一般的に child_process.spawn() と同じです。タイムアウトが発生し、killSignal が送信された場合、プロセスが完全に終了するまでメソッドは戻りません。プロセスが SIGTERM シグナルをインターセプトして処理し、終了しない場合、親プロセスは子プロセスが終了するまで待機します。

shell オプションが有効になっている場合、サニタイズされていないユーザー入力をこの関数に渡さないでください。シェルメタ文字を含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。

クラス: ChildProcess

追加: v2.2.0

ChildProcess のインスタンスは、生成された子プロセスを表します。

ChildProcess のインスタンスは、直接作成することを意図していません。代わりに、ChildProcess のインスタンスを作成するには、child_process.spawn()child_process.exec()child_process.execFile()、または child_process.fork() メソッドを使用します。

イベント: 'close'

追加: v0.7.7

  • code <number> 子プロセスが単独で終了した場合の終了コード。
  • signal <string> 子プロセスが終了したシグナル。

'close' イベントは、プロセスが終了し、かつ 子プロセスの stdio ストリームが閉じられた後に発行されます。これは、複数のプロセスが同じ stdio ストリームを共有する可能性があるため、'exit' イベントとは異なります。'close' イベントは、'exit' がすでに発行された後、または子プロセスの起動に失敗した場合は 'error' が発行された後に常に発行されます。

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(`child process close all stdio with code ${code}`)
})

ls.on('exit', 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.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}`)
})

イベント: 'disconnect'

追加: v0.7.2

'disconnect' イベントは、親プロセスで subprocess.disconnect() メソッドを呼び出した後、または子プロセスで process.disconnect() を呼び出した後に発生します。切断後、メッセージの送受信はできなくなり、subprocess.connected プロパティは false になります。

イベント: 'error'

'error' イベントは、次のいずれかの状況で発生します。

  • プロセスを生成できなかった場合。
  • プロセスを強制終了できなかった場合。
  • 子プロセスへのメッセージ送信に失敗した場合。
  • 子プロセスが signal オプションによって中断された場合。

'exit' イベントは、エラー発生後に発生する場合としない場合があります。'exit' イベントと 'error' イベントの両方をリッスンする場合は、ハンドラー関数が複数回誤って呼び出されないように注意してください。

subprocess.kill() および subprocess.send() も参照してください。

イベント: 'exit'

追加: v0.1.90

  • code <number> 子プロセスが自力で終了した場合の終了コード。
  • signal <string> 子プロセスが終了した原因となったシグナル。

'exit' イベントは、子プロセスが終了した後に発生します。プロセスが終了した場合、code はプロセスの最終終了コードであり、それ以外の場合は null です。プロセスがシグナルの受信により終了した場合、signal はシグナルの文字列名であり、それ以外の場合は null です。いずれか一方は常に非 null になります。

'exit' イベントがトリガーされると、子プロセスの stdio ストリームがまだ開いている可能性があります。

Node.js は SIGINT および SIGTERM のシグナルハンドラーを設定し、Node.js プロセスはこれらのシグナルの受信によって直ちに終了することはありません。むしろ、Node.js は一連のクリーンアップアクションを実行し、その後、処理されたシグナルを再度発生させます。

waitpid(2) を参照してください。

イベント: 'message'

追加: v0.5.9

'message' イベントは、子プロセスが process.send() を使用してメッセージを送信したときに発生します。

メッセージはシリアライズとパースを通過します。結果として得られるメッセージは、最初に送信されたものと同じではない可能性があります。

子プロセスの生成時に serialization オプションが 'advanced' に設定されていた場合、message 引数には JSON が表現できないデータが含まれる可能性があります。詳細については、高度なシリアライズ を参照してください。

イベント: 'spawn'

追加: v15.1.0, v14.17.0

'spawn' イベントは、子プロセスが正常に生成された後に一度だけ発行されます。子プロセスが正常に生成されなかった場合、'spawn' イベントは発行されず、代わりに 'error' イベントが発行されます。

発行された場合、'spawn' イベントは他のすべてのイベントよりも前、および stdout または stderr を介してデータを受信する前に発生します。

'spawn' イベントは、生成されたプロセスでエラーが発生したかどうかに関係なく発生します。たとえば、bash some-command が正常に生成された場合、'spawn' イベントが発生しますが、bashsome-command の生成に失敗する可能性があります。この注意点は、{ shell: true } を使用する場合にも適用されます。

subprocess.channel

[履歴]

バージョン変更点
v14.0.0オブジェクトが誤ってネイティブ C++ バインディングを公開しなくなった。
v7.1.0追加: v7.1.0
  • <Object> 子プロセスへの IPC チャネルを表すパイプ。

subprocess.channel プロパティは、子プロセスの IPC チャネルへの参照です。IPC チャネルが存在しない場合、このプロパティは undefined になります。

subprocess.channel.ref()

追加: v7.1.0

このメソッドは、.unref() が以前に呼び出された場合、IPC チャネルが親プロセスのイベントループを実行し続けるようにします。

subprocess.channel.unref()

追加: v7.1.0

このメソッドは、IPC チャネルが親プロセスのイベントループを実行し続けず、チャネルが開いている間でも終了できるようにします。

subprocess.connected

追加: v0.7.2

  • <boolean> subprocess.disconnect() が呼び出された後、false に設定されます。

subprocess.connected プロパティは、子プロセスとの間でメッセージを送受信できるかどうかを示します。subprocess.connectedfalse の場合、メッセージを送受信することはできません。

subprocess.disconnect()

追加: v0.7.2

親プロセスと子プロセス間の IPC チャネルを閉じ、子プロセスが他の接続で存続している必要がなくなると、正常に終了できるようにします。このメソッドを呼び出した後、親プロセスと子プロセスの両方(それぞれ)の subprocess.connected プロパティと process.connected プロパティは false に設定され、プロセス間でメッセージを渡すことはできなくなります。

受信中のメッセージがない場合、'disconnect' イベントが発行されます。これは、subprocess.disconnect() を呼び出した直後にトリガーされることがほとんどです。

子プロセスが Node.js インスタンス(例えば、child_process.fork() を使用して生成された場合)である場合、子プロセス内で process.disconnect() メソッドを呼び出して、IPC チャネルを閉じることもできます。

subprocess.exitCode

subprocess.exitCode プロパティは、子プロセスの終了コードを示します。子プロセスがまだ実行中の場合、このフィールドは null になります。

subprocess.kill([signal])

追加: v0.1.90

subprocess.kill() メソッドは、子プロセスにシグナルを送信します。引数が指定されていない場合、プロセスには 'SIGTERM' シグナルが送信されます。利用可能なシグナルの一覧については、signal(7) を参照してください。この関数は、kill(2) が成功した場合は true を、それ以外の場合は false を返します。

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

grep.on('close', (code, signal) => {
  console.log(`子プロセスはシグナル ${signal} を受信したため終了しました`)
})

// プロセスに SIGHUP を送信します。
grep.kill('SIGHUP')
js
import { spawn } from 'node:child_process'
const grep = spawn('grep', ['ssh'])

grep.on('close', (code, signal) => {
  console.log(`子プロセスはシグナル ${signal} を受信したため終了しました`)
})

// プロセスに SIGHUP を送信します。
grep.kill('SIGHUP')

シグナルを配信できない場合、ChildProcess オブジェクトは 'error' イベントを発行する可能性があります。すでに終了した子プロセスにシグナルを送信することはエラーではありませんが、予期しない結果をもたらす可能性があります。特に、プロセス識別子(PID)が別のプロセスに再割り当てされた場合、シグナルは代わりにそのプロセスに配信され、予期しない結果になる可能性があります。

この関数は kill と呼ばれていますが、子プロセスに配信されるシグナルは、実際にはプロセスを終了させない場合があります。

詳細については、kill(2) を参照してください。

POSIX シグナルが存在しない Windows では、signal 引数は 'SIGKILL', 'SIGTERM', 'SIGINT' および 'SIGQUIT' を除いて無視され、プロセスは常に強制的に突然終了します('SIGKILL' と同様)。詳細については、シグナルイベント を参照してください。

Linux では、子プロセスの親を強制終了しようとしても、子プロセスの子プロセスは終了しません。これは、シェルで新しいプロセスを実行する場合、または ChildProcessshell オプションを使用する場合に発生する可能性が高くなります。

js
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() // シェル内のNode.jsプロセスは終了しません。
}, 2000)
js
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() // シェル内のNode.jsプロセスは終了しません。
}, 2000)

subprocess[Symbol.dispose]()

追加: v20.5.0, v18.18.0

[安定版: 1 - 試験的]

安定版: 1 安定版: 1 - 試験的

'SIGTERM'subprocess.kill() を呼び出します。

subprocess.killed

追加: v0.5.10

  • <boolean> subprocess.kill() が子プロセスに正常にシグナルを送信するために使用された後、true に設定されます。

subprocess.killed プロパティは、子プロセスが subprocess.kill() から正常にシグナルを受信したかどうかを示します。killed プロパティは、子プロセスが終了したことを示すものではありません。

subprocess.pid

追加: v0.1.90

子プロセスのプロセス識別子(PID)を返します。エラーが原因で子プロセスの生成に失敗した場合、値は undefined になり、error が発生します。

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

console.log(`生成された子プロセス pid: ${grep.pid}`)
grep.stdin.end()
js
import { spawn } from 'node:child_process'
const grep = spawn('grep', ['ssh'])

console.log(`生成された子プロセス pid: ${grep.pid}`)
grep.stdin.end()

subprocess.ref()

追加: v0.7.10

subprocess.unref() の呼び出し後に subprocess.ref() を呼び出すと、子プロセスの削除された参照カウントが復元され、親プロセスは自身が終了する前に子プロセスの終了を待機することを強制します。

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])

[履歴]

バージョン変更
v5.8.0options パラメーターと、特に keepOpen オプションがサポートされるようになりました。
v5.0.0このメソッドは、フロー制御のためにブール値を返すようになりました。
v4.0.0callback パラメーターがサポートされるようになりました。
v0.5.9追加: v0.5.9
  • message <Object>

  • sendHandle <Handle> | <undefined> undefined、または net.Socketnet.Server、あるいは dgram.Socket オブジェクト。

  • options <Object> options 引数(存在する場合)は、特定の種類のハンドルの送信をパラメーター化するために使用されるオブジェクトです。 options は以下のプロパティをサポートします。

    • keepOpen <boolean> net.Socket のインスタンスを渡すときに使用できる値。 true の場合、ソケットは送信プロセスで開いたままになります。 デフォルト: false
  • callback <Function>

  • 戻り値: <boolean>

親プロセスと子プロセスの間で IPC チャネルが確立された場合(つまり、child_process.fork() を使用する場合)、subprocess.send() メソッドを使用して子プロセスにメッセージを送信できます。子プロセスが Node.js インスタンスの場合、これらのメッセージは 'message' イベントを介して受信できます。

メッセージはシリアル化と解析を経ます。結果として得られるメッセージは、最初に送信されたものと同じではない可能性があります。

たとえば、親スクリプトでは次のようになります。

js
const { fork } = require('node:child_process')
const forkedProcess = fork(`${__dirname}/sub.js`)

forkedProcess.on('message', message => {
  console.log('親がメッセージを受信:', message)
})

// 子に CHILD got message: { 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('親がメッセージを受信:', message)
})

// 子に CHILD got message: { hello: 'world' } と出力させます
forkedProcess.send({ hello: 'world' })

次に、子スクリプト 'sub.js' は次のようになります。

js
process.on('message', message => {
  console.log('子がメッセージを受信:', message)
})

// 親に PARENT got message: { foo: 'bar', baz: null } と出力させます
process.send({ foo: 'bar', baz: NaN })

子 Node.js プロセスには、子プロセスが親プロセスにメッセージを送信できるようにする独自の process.send() メソッドがあります。

{cmd: 'NODE_foo'} メッセージを送信する場合、特別なケースがあります。cmd プロパティに NODE_ プレフィックスを含むメッセージは、Node.js コア内で使用するために予約されており、子プロセスの 'message' イベントでは発行されません。むしろ、このようなメッセージは 'internalMessage' イベントを使用して発行され、Node.js 内部で消費されます。アプリケーションは、このようなメッセージの使用や 'internalMessage' イベントのリスニングを避ける必要があります。これは、予告なしに変更される可能性があるためです。

subprocess.send() に渡すことができるオプションの sendHandle 引数は、TCP サーバーまたはソケットオブジェクトを子プロセスに渡すためのものです。子プロセスは、'message' イベントに登録されたコールバック関数に渡される 2 番目の引数としてオブジェクトを受け取ります。ソケットで受信およびバッファリングされたデータは、子に送信されません。IPC ソケットの送信は、Windows ではサポートされていません。

オプションの callback は、メッセージが送信された後、子プロセスがそれを受信する前に呼び出される関数です。この関数は、成功した場合は null、失敗した場合は Error オブジェクトの 1 つの引数を付けて呼び出されます。

callback 関数が提供されておらず、メッセージを送信できない場合、ChildProcess オブジェクトによって 'error' イベントが発行されます。これは、たとえば、子プロセスがすでに終了している場合に発生する可能性があります。

チャネルが閉じている場合、または未送信メッセージのバックログが、それ以上送信するのが賢明でないしきい値を超えた場合、subprocess.send()false を返します。それ以外の場合、メソッドは true を返します。 callback 関数を使用して、フロー制御を実装できます。

例:サーバーオブジェクトの送信

sendHandle引数は、たとえば、次の例に示すように、TCP サーバーオブジェクトのハンドルを子プロセスに渡すために使用できます。

js
const { fork } = require('node:child_process')
const { createServer } = require('node:net')

const subprocess = fork('subprocess.js')

// サーバーオブジェクトを開き、ハンドルを送信します。
const server = createServer()
server.on('connection', socket => {
  socket.end('親によって処理されました')
})
server.listen(1337, () => {
  subprocess.send('server', server)
})
js
import { fork } from 'node:child_process'
import { createServer } from 'node:net'

const subprocess = fork('subprocess.js')

// サーバーオブジェクトを開き、ハンドルを送信します。
const server = createServer()
server.on('connection', socket => {
  socket.end('親によって処理されました')
})
server.listen(1337, () => {
  subprocess.send('server', server)
})

子プロセスは、次のようにサーバーオブジェクトを受信します。

js
process.on('message', (m, server) => {
  if (m === 'server') {
    server.on('connection', socket => {
      socket.end('子によって処理されました')
    })
  }
})

サーバーが親と子の間で共有されると、一部の接続は親によって処理され、一部は子によって処理される可能性があります。

上記の例では、node:netモジュールを使用して作成されたサーバーを使用していますが、node:dgramモジュールのサーバーは、'connection'の代わりに'message'イベントをリッスンし、server.listen()の代わりにserver.bind()を使用する点を除いて、まったく同じワークフローを使用します。ただし、これは Unix プラットフォームでのみサポートされています。

例:ソケットオブジェクトの送信

同様に、sendHandler引数を使用して、ソケットのハンドルを子プロセスに渡すことができます。次の例では、それぞれ「通常」または「特別」の優先度で接続を処理する 2 つの子を生成します。

js
const { fork } = require('node:child_process')
const { createServer } = require('node:net')

const normal = fork('subprocess.js', ['normal'])
const special = fork('subprocess.js', ['special'])

// サーバーを開き、ソケットを子に送信します。pauseOnConnectを使用して、
// 子プロセスに送信される前にソケットが読み取られるのを防ぎます。
const server = createServer({ pauseOnConnect: true })
server.on('connection', socket => {
  // これが特別な優先度の場合...
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket)
    return
  }
  // これは通常の優先度です。
  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'])

// サーバーを開き、ソケットを子に送信します。pauseOnConnectを使用して、
// 子プロセスに送信される前にソケットが読み取られるのを防ぎます。
const server = createServer({ pauseOnConnect: true })
server.on('connection', socket => {
  // これが特別な優先度の場合...
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket)
    return
  }
  // これは通常の優先度です。
  normal.send('socket', socket)
})
server.listen(1337)

subprocess.jsは、イベントコールバック関数に渡される 2 番目の引数としてソケットハンドルを受け取ります。

js
process.on('message', (m, socket) => {
  if (m === 'socket') {
    if (socket) {
      // クライアントソケットが存在することを確認します。
      // ソケットは、送信されてから子プロセスで受信されるまでの間に閉じられる可能性があります。
      socket.end(`Request handled with ${process.argv[2]} priority`)
    }
  }
})

サブプロセスに渡されたソケットで.maxConnectionsを使用しないでください。親はソケットが破棄されたことを追跡できません。

サブプロセス内の'message'ハンドラーは、接続を子に送信するのにかかる時間中に接続が閉じられている可能性があるため、socketが存在することを確認する必要があります。

subprocess.signalCode

subprocess.signalCodeプロパティは、子プロセスがシグナルを受信した場合、そのシグナルを示します。受信しなかった場合はnullになります。

subprocess.spawnargs

subprocess.spawnargsプロパティは、子プロセスが起動された際に使用されたコマンドライン引数の完全なリストを表します。

subprocess.spawnfile

subprocess.spawnfileプロパティは、起動された子プロセスの実行可能ファイル名を示します。

child_process.fork()の場合、その値はprocess.execPathと等しくなります。child_process.spawn()の場合、その値は実行可能ファイルの名前になります。child_process.exec()の場合、その値は子プロセスが起動されたシェルの名前になります。

subprocess.stderr

追加: v0.1.90

子プロセスのstderrを表すReadable Streamです。

子プロセスがstdio[2]'pipe'以外に設定して spawn された場合、これはnullになります。

subprocess.stderrsubprocess.stdio[2]のエイリアスです。どちらのプロパティも同じ値を参照します。

子プロセスが正常に spawn されなかった場合、subprocess.stderrプロパティはnullまたはundefinedになることがあります。

subprocess.stdin

追加: v0.1.90

子プロセスの stdin を表す Writable Stream です。

子プロセスがすべての入力を読み込むのを待っている場合、このストリームが end() を介して閉じられるまで子プロセスは続行されません。

子プロセスが stdio[0]'pipe' 以外に設定して生成された場合、これは null になります。

subprocess.stdinsubprocess.stdio[0] のエイリアスです。どちらのプロパティも同じ値を参照します。

子プロセスが正常に生成されなかった場合、subprocess.stdin プロパティは null または undefined になる可能性があります。

subprocess.stdio

追加: v0.7.10

child_process.spawn() に渡された stdio オプションで 'pipe' の値に設定されている位置に対応する、子プロセスへのパイプの疎配列です。subprocess.stdio[0]subprocess.stdio[1]subprocess.stdio[2] は、それぞれ subprocess.stdinsubprocess.stdoutsubprocess.stderr としても利用できます。

次の例では、子プロセスの fd 1 (stdout) のみがパイプとして構成されているため、親の subprocess.stdio[1] のみがストリームであり、配列内の他のすべての値は 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, // 子プロセスに親の stdin を使用します。
    'pipe', // 子プロセスの stdout を親にパイプします。
    fs.openSync('err.out', 'w'), // 子プロセスの stderr をファイルにリダイレクトします。
  ],
})

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, // 子プロセスに親の stdin を使用します。
    'pipe', // 子プロセスの stdout を親にパイプします。
    fs.openSync('err.out', 'w'), // 子プロセスの stderr をファイルにリダイレクトします。
  ],
})

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)

子プロセスが正常に生成されなかった場合、subprocess.stdio プロパティは undefined になる可能性があります。

subprocess.stdout

追加: v0.1.90

子プロセスの stdout を表す Readable Stream

子プロセスが stdio[1]'pipe' 以外に設定して起動された場合、これは null になります。

subprocess.stdoutsubprocess.stdio[1] のエイリアスです。両方のプロパティは同じ値を参照します。

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

子プロセスが正常に起動できなかった場合、subprocess.stdout プロパティは null または undefined になることがあります。

subprocess.unref()

追加: v0.7.10

デフォルトでは、親プロセスは分離された子プロセスの終了を待ちます。特定の subprocess が終了するのを親プロセスが待たないようにするには、subprocess.unref() メソッドを使用します。そうすることで、親のイベントループは、子プロセスをその参照カウントに含めなくなり、子プロセスと親プロセスの間に確立された IPC チャネルがない限り、親が子プロセスとは独立して終了できるようになります。

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 と Unicode

maxBuffer オプションは、stdout または stderr で許可される最大バイト数を指定します。この値を超えると、子プロセスは終了します。これは、UTF-8 や UTF-16 などのマルチバイト文字エンコーディングを含む出力に影響します。たとえば、console.log('中文测试') は 4 文字しかありませんが、13 バイトの UTF-8 エンコードされたバイトを stdout に送信します。

シェルの要件

シェルは -c スイッチを理解する必要があります。シェルが 'cmd.exe' の場合、/d /s /c スイッチを理解し、コマンドライン解析が互換性を持つ必要があります。

Windows のデフォルトシェル

Microsoft は、ルート環境の %COMSPEC%'cmd.exe' のパスを含める必要があると規定していますが、子プロセスは常に同じ要件に従うわけではありません。したがって、シェルを生成できる child_process 関数では、process.env.ComSpec が利用できない場合、フォールバックとして 'cmd.exe' が使用されます。

高度なシリアライズ

追加: v13.2.0, v12.16.0

子プロセスは、HTML 構造化クローンアルゴリズムに基づく、node:v8 モジュールのシリアライズ API に基づいた IPC のためのシリアライズメカニズムをサポートしています。これは一般的により強力で、BigIntMapSetArrayBufferTypedArrayBufferErrorRegExp など、より多くの組み込み JavaScript オブジェクト型をサポートします。

ただし、このフォーマットは JSON の完全なスーパーセットではなく、たとえば、このような組み込み型のオブジェクトに設定されたプロパティは、シリアライズステップを介して渡されません。さらに、渡されるデータの構造によっては、パフォーマンスが JSON と同等ではない場合があります。したがって、この機能は child_process.spawn() または child_process.fork() を呼び出すときに serialization オプションを 'advanced' に設定することでオプトインする必要があります。