子プロセス
ソースコード: lib/child_process.js
node:child_process
モジュールは、popen(3)
と同様の方法で(ただし同一ではない)、サブプロセスを生成する機能を提供します。この機能は主に child_process.spawn()
関数によって提供されます。
const { spawn } = require('node:child_process')
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.stderr.on('data', data => {
console.error(`stderr: ${data}`)
})
ls.on('close', code => {
console.log(`子プロセスはコード ${code} で終了しました`)
})
import { spawn } from 'node:child_process'
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.stderr.on('data', data => {
console.error(`stderr: ${data}`)
})
ls.on('close', code => {
console.log(`子プロセスはコード ${code} で終了しました`)
})
デフォルトでは、stdin
、stdout
、および stderr
のパイプが、親の Node.js プロセスと生成されたサブプロセスの間に確立されます。これらのパイプには、制限された(プラットフォーム固有の)容量があります。サブプロセスがキャプチャされずにその制限を超える量を stdout に書き込むと、サブプロセスはパイプバッファがより多くのデータを受け入れるのを待機してブロックします。これは、シェルでのパイプの動作と同じです。出力が消費されない場合は、{ stdio: 'ignore' }
オプションを使用してください。
コマンド検索は、options
オブジェクトに env
が含まれている場合は options.env.PATH
環境変数を使用して実行されます。それ以外の場合は、process.env.PATH
が使用されます。 options.env
が PATH
なしで設定されている場合、Unix では /usr/bin:/bin
のデフォルトの検索パス(execvpe/execvp についてはオペレーティングシステムのマニュアルを参照してください)で検索が実行され、Windows では現在のプロセスの環境変数 PATH
が使用されます。
Windows では、環境変数は大文字と小文字を区別しません。Node.js は env
キーを辞書式順にソートし、大文字と小文字を区別せずに一致する最初のものを使用します。最初の(辞書順で)エントリのみがサブプロセスに渡されます。これにより、PATH
や Path
など、同じキーの複数のバリアントを持つオブジェクトを 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.exec()
: シェルを生成し、そのシェル内でコマンドを実行し、完了時にstdout
とstderr
をコールバック関数に渡します。child_process.execFile()
: デフォルトでは最初にシェルを生成せずにコマンドを直接生成することを除いて、child_process.exec()
と同様です。child_process.fork()
: 新しい Node.js プロセスを生成し、親と子の間でメッセージを送信できるようにする IPC 通信チャネルが確立された指定されたモジュールを呼び出します。child_process.execSync()
: Node.js イベントループをブロックする、child_process.exec()
の同期バージョンです。child_process.execFileSync()
: Node.js イベントループをブロックする、child_process.execFile()
の同期バージョンです。
シェルスクリプトの自動化など、特定のユースケースでは、同期カウンターパート がより便利な場合があります。しかし多くの場合、同期メソッドは、生成されたプロセスの完了中にイベントループを停止させるため、パフォーマンスに大きな影響を与える可能性があります。
非同期プロセス生成
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()
が行っていることです)。いずれの場合も、スクリプトのファイル名にスペースが含まれている場合は、引用符で囲む必要があります。
// 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) => {
// ...
})
// 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.0 | AbortSignal のサポートが追加されました。 |
v16.4.0, v14.18.0 | cwd オプションは file: プロトコルを使用する WHATWG URL オブジェクトにできます。 |
v8.8.0 | windowsHide オプションがサポートされるようになりました。 |
v0.1.90 | v0.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
文字列はシェルによって直接処理され、特殊文字(シェル によって異なります)は適切に処理する必要があります。
const { exec } = require('node:child_process')
exec('"/path/to/test file/test.sh" arg1 arg2')
// パス内のスペースが複数の引数の区切り文字として解釈されないように、二重引用符を使用します。
exec('echo "The \\$HOME variable is $HOME"')
// $HOME 変数は、最初のインスタンスではエスケープされますが、2 番目のインスタンスではエスケープされません。
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)
を使用して呼び出されます。成功した場合、error
は null
になります。エラーが発生した場合、error
は Error
のインスタンスになります。error.code
プロパティは、プロセスの終了コードになります。慣例により、0
以外の終了コードはエラーを示します。error.signal
は、プロセスを終了したシグナルになります。
コールバックに渡される stdout
および stderr
引数には、子プロセスの stdout および stderr 出力が含まれます。デフォルトでは、Node.js は出力を UTF-8 としてデコードし、文字列をコールバックに渡します。encoding
オプションを使用して、stdout および stderr 出力のデコードに使用する文字エンコーディングを指定できます。encoding
が 'buffer'
または認識されない文字エンコーディングである場合、代わりに Buffer
オブジェクトがコールバックに渡されます。
const { exec } = require('node:child_process')
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`)
return
}
console.log(`stdout: ${stdout}`)
console.error(`stderr: ${stderr}`)
})
import { exec } from 'node:child_process'
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`)
return
}
console.log(`stdout: ${stdout}`)
console.error(`stderr: ${stderr}`)
})
timeout
が 0
より大きい場合、子プロセスが timeout
ミリ秒より長く実行されると、親プロセスは killSignal
プロパティで識別されるシグナル(デフォルトは 'SIGTERM'
)を送信します。
exec(3)
POSIX システムコールとは異なり、child_process.exec()
は既存のプロセスを置き換えず、シェルを使用してコマンドを実行します。
このメソッドが util.promisify()
ed バージョンとして呼び出された場合、stdout
および stderr
プロパティを持つ Object
の Promise
を返します。返された ChildProcess
インスタンスは、child
プロパティとして Promise
にアタッチされます。エラー(0 以外の終了コードになるエラーを含む)が発生した場合、コールバックで指定されたものと同じ error
オブジェクトで拒否されたプロミスが返されますが、追加のプロパティ stdout
および stderr
が付いています。
const util = require('node:util')
const exec = util.promisify(require('node:child_process').exec)
async function lsExample() {
const { stdout, stderr } = await exec('ls')
console.log('stdout:', stdout)
console.error('stderr:', stderr)
}
lsExample()
import { promisify } from 'node:util'
import child_process from 'node:child_process'
const exec = promisify(child_process.exec)
async function lsExample() {
const { stdout, stderr } = await exec('ls')
console.log('stdout:', stdout)
console.error('stderr:', stderr)
}
lsExample()
signal
オプションが有効になっている場合、対応する AbortController
で .abort()
を呼び出すことは、子プロセスで .kill()
を呼び出すことと似ていますが、コールバックに渡されるエラーは AbortError
になります。
const { exec } = require('node:child_process')
const controller = new AbortController()
const { signal } = controller
const child = exec('grep ssh', { signal }, error => {
console.error(error) // an AbortError
})
controller.abort()
import { exec } from 'node:child_process'
const controller = new AbortController()
const { signal } = controller
const child = exec('grep ssh', { signal }, error => {
console.error(error) // an AbortError
})
controller.abort()
child_process.execFile(file[, args][, options][, callback])
[履歴]
バージョン | 変更点 |
---|---|
v16.4.0, v14.18.0 | cwd オプションは、file: プロトコルを使用する WHATWG URL オブジェクトにすることができます。 |
v15.4.0, v14.17.0 | AbortSignal のサポートが追加されました。 |
v8.8.0 | windowsHide オプションがサポートされるようになりました。 |
v0.1.91 | v0.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 リダイレクトやファイル グロビングなどの動作はサポートされていません。
const { execFile } = require('node:child_process')
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
if (error) {
throw error
}
console.log(stdout)
})
import { execFile } from 'node:child_process'
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
if (error) {
throw error
}
console.log(stdout)
})
コールバックに渡される stdout
および stderr
引数には、子プロセスの stdout および stderr 出力が含まれます。デフォルトでは、Node.js は出力を UTF-8 としてデコードし、文字列をコールバックに渡します。encoding
オプションを使用して、stdout および stderr 出力のデコードに使用される文字エンコーディングを指定できます。encoding
が 'buffer'
であるか、認識されない文字エンコーディングの場合、代わりに Buffer
オブジェクトがコールバックに渡されます。
このメソッドが util.promisify()
化されたバージョンとして呼び出された場合、stdout
および stderr
プロパティを持つ Object
の Promise
を返します。返された ChildProcess
インスタンスは、Promise
に child
プロパティとしてアタッチされます。エラーが発生した場合 (0 以外の終了コードを招くエラーを含む)、拒否された Promise が返され、コールバックで指定されたのと同じ error
オブジェクトが返されますが、2 つの追加プロパティ stdout
および stderr
が追加されます。
const util = require('node:util')
const execFile = util.promisify(require('node:child_process').execFile)
async function getVersion() {
const { stdout } = await execFile('node', ['--version'])
console.log(stdout)
}
getVersion()
import { promisify } from 'node:util'
import child_process from 'node:child_process'
const execFile = promisify(child_process.execFile)
async function getVersion() {
const { stdout } = await execFile('node', ['--version'])
console.log(stdout)
}
getVersion()
shell
オプションが有効になっている場合は、サニタイズされていないユーザー入力をこの関数に渡さないでください。シェル メタキャラクターを含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。
signal
オプションが有効になっている場合、対応する AbortController
で .abort()
を呼び出すことは、子プロセスで .kill()
を呼び出すのと似ていますが、コールバックに渡されるエラーは AbortError
になります。
const { execFile } = require('node:child_process')
const controller = new AbortController()
const { signal } = controller
const child = execFile('node', ['--version'], { signal }, error => {
console.error(error) // an AbortError
})
controller.abort()
import { execFile } from 'node:child_process'
const controller = new AbortController()
const { signal } = controller
const child = execFile('node', ['--version'], { signal }, error => {
console.error(error) // an AbortError
})
controller.abort()
child_process.fork(modulePath[, args][, options])
[履歴]
バージョン | 変更点 |
---|---|
v17.4.0, v16.14.0 | modulePath パラメーターは、file: プロトコルを使用する WHATWG URL オブジェクトにできます。 |
v16.4.0, v14.18.0 | cwd オプションは、file: プロトコルを使用する WHATWG URL オブジェクトにできます。 |
v15.13.0, v14.18.0 | timeout が追加されました。 |
v15.11.0, v14.18.0 | AbortSignal の killSignal が追加されました。 |
v15.6.0, v14.17.0 | AbortSignal のサポートが追加されました。 |
v13.2.0, v12.16.0 | serialization オプションがサポートされるようになりました。 |
v8.0.0 | stdio オプションは文字列にできるようになりました。 |
v6.4.0 | stdio オプションがサポートされるようになりました。 |
v0.5.0 | 追加: v0.5.0 |
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
になります。
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() // 子プロセスを停止します
}
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.0 | cwd オプションに file: プロトコルを使用する WHATWG URL オブジェクトを指定できるようになりました。 |
v15.13.0, v14.18.0 | timeout が追加されました。 |
v15.11.0, v14.18.0 | AbortSignal の killSignal が追加されました。 |
v15.5.0, v14.17.0 | AbortSignal のサポートが追加されました。 |
v13.2.0, v12.16.0 | serialization オプションがサポートされるようになりました。 |
v8.8.0 | windowsHide オプションがサポートされるようになりました。 |
v6.4.0 | argv0 オプションがサポートされるようになりました。 |
v5.7.0 | shell オプションがサポートされるようになりました。 |
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 番目の引数を使用して追加のオプションを指定できます。これらのデフォルトは次のとおりです。
const defaults = {
cwd: undefined,
env: process.env,
}
cwd
を使用して、プロセスが生成されるワーキングディレクトリを指定します。指定しない場合、デフォルトは現在のワーキングディレクトリを継承します。指定した場合でも、パスが存在しない場合は、子プロセスは ENOENT
エラーを発行してすぐに終了します。ENOENT
はコマンドが存在しない場合にも発行されます。
env
を使用して、新しいプロセスに表示される環境変数を指定します。デフォルトは process.env
です。
env
の undefined
値は無視されます。
ls -lh /usr
を実行し、stdout
、stderr
、および終了コードをキャプチャする例:
const { spawn } = require('node:child_process')
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.stderr.on('data', data => {
console.error(`stderr: ${data}`)
})
ls.on('close', code => {
console.log(`child process exited with code ${code}`)
})
import { spawn } from 'node:child_process'
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.stderr.on('data', data => {
console.error(`stderr: ${data}`)
})
ls.on('close', code => {
console.log(`child process exited with code ${code}`)
})
例: ps ax | grep ssh
を実行する非常に手の込んだ方法
const { spawn } = require('node:child_process')
const ps = spawn('ps', ['ax'])
const grep = spawn('grep', ['ssh'])
ps.stdout.on('data', data => {
grep.stdin.write(data)
})
ps.stderr.on('data', data => {
console.error(`ps stderr: ${data}`)
})
ps.on('close', code => {
if (code !== 0) {
console.log(`ps process exited with code ${code}`)
}
grep.stdin.end()
})
grep.stdout.on('data', data => {
console.log(data.toString())
})
grep.stderr.on('data', data => {
console.error(`grep stderr: ${data}`)
})
grep.on('close', code => {
if (code !== 0) {
console.log(`grep process exited with code ${code}`)
}
})
import { spawn } from 'node:child_process'
const ps = spawn('ps', ['ax'])
const grep = spawn('grep', ['ssh'])
ps.stdout.on('data', data => {
grep.stdin.write(data)
})
ps.stderr.on('data', data => {
console.error(`ps stderr: ${data}`)
})
ps.on('close', code => {
if (code !== 0) {
console.log(`ps process exited with code ${code}`)
}
grep.stdin.end()
})
grep.stdout.on('data', data => {
console.log(data.toString())
})
grep.stderr.on('data', data => {
console.error(`grep stderr: ${data}`)
})
grep.on('close', code => {
if (code !== 0) {
console.log(`grep process exited with code ${code}`)
}
})
spawn
が失敗した場合の確認例:
const { spawn } = require('node:child_process')
const subprocess = spawn('bad_command')
subprocess.on('error', err => {
console.error('Failed to start subprocess.')
})
import { spawn } from 'node:child_process'
const subprocess = spawn('bad_command')
subprocess.on('error', err => {
console.error('Failed to start subprocess.')
})
特定のプラットフォーム (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
になります。
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() // 子プロセスを停止します
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.detached
をtrue
に設定すると、親プロセスが終了した後も子プロセスが実行を継続できるようになります。子プロセスは独自のコンソールウィンドウを持つようになります。子プロセスで有効にすると、無効にすることはできません。
Windows 以外のプラットフォームでは、options.detached
がtrue
に設定されている場合、子プロセスは新しいプロセスグループとセッションのリーダーになります。子プロセスは、デタッチされているかどうかに関係なく、親プロセスが終了した後も実行を継続できます。詳細についてはsetsid(2)
を参照してください。
デフォルトでは、親プロセスはデタッチされた子プロセスが終了するのを待ちます。親プロセスが特定のsubprocess
の終了を待機しないようにするには、subprocess.unref()
メソッドを使用します。これにより、親プロセスのイベントループが子プロセスを参照カウントに含めなくなり、子プロセスと親プロセスの間に確立された IPC チャネルがない限り、親プロセスは子プロセスとは独立して終了できます。
detached
オプションを使用して長時間実行されるプロセスを開始する場合、プロセスが親に接続されていないstdio
構成が提供されない限り、親が終了した後もバックグラウンドで実行されません。親プロセスのstdio
が継承された場合、子プロセスは制御端末に接続されたままになります。
親の終了を無視するために、デタッチして親のstdio
ファイルディスクリプタを無視することによる長時間実行プロセスの例:
const { spawn } = require('node:child_process')
const process = require('node:process')
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
import { spawn } from 'node:child_process'
import process from 'node:process'
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
あるいは、子プロセスの出力をファイルにリダイレクトすることもできます。
const { openSync } = require('node:fs')
const { spawn } = require('node:child_process')
const out = openSync('./out.log', 'a')
const err = openSync('./out.log', 'a')
const subprocess = spawn('prg', [], {
detached: true,
stdio: ['ignore', out, err],
})
subprocess.unref()
import { openSync } from 'node:fs'
import { spawn } from 'node:child_process'
const out = openSync('./out.log', 'a')
const err = openSync('./out.log', 'a')
const subprocess = spawn('prg', [], {
detached: true,
stdio: ['ignore', out, err],
})
subprocess.unref()
options.stdio
[履歴]
バージョン | 変更点 |
---|---|
v15.6.0, v14.18.0 | overlapped stdio フラグが追加されました。 |
v3.3.1 | 値 0 がファイル記述子として受け入れられるようになりました。 |
v0.7.10 | 追加: v0.7.10 |
options.stdio
オプションは、親プロセスと子プロセスの間に確立されるパイプを設定するために使用されます。デフォルトでは、子プロセスの stdin、stdout、および stderr は、ChildProcess
オブジェクト上の対応する subprocess.stdin
、subprocess.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 を指定して、親と子の間に追加のパイプを作成できます。値は次のいずれかになります。
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'] })
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.0 | cwd オプションは、file: プロトコルを使用する WHATWG URL オブジェクトにできます。 |
v10.10.0 | input オプションは、任意の TypedArray または DataView にできるようになりました。 |
v8.8.0 | windowsHide オプションがサポートされるようになりました。 |
v8.0.0 | input オプションは、Uint8Array にできるようになりました。 |
v6.2.1, v4.5.0 | encoding オプションは、明示的に 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
(シェルなし)。
child_process.execFileSync()
メソッドは、一般的に child_process.execFile()
と同一ですが、子プロセスが完全に終了するまでメソッドが戻らないという例外があります。タイムアウトが発生し、killSignal
が送信された場合、プロセスが完全に終了するまでメソッドは戻りません。
子プロセスが SIGTERM
シグナルをインターセプトして処理し、終了しない場合でも、親プロセスは子プロセスが終了するまで待機します。
プロセスがタイムアウトするか、ゼロ以外の終了コードを持つ場合、このメソッドは、基盤となる child_process.spawnSync()
の完全な結果を含む Error
をスローします。
shell
オプションが有効になっている場合は、この関数にサニタイズされていないユーザー入力を渡さないでください。シェル メタキャラクターを含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。
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 })
}
}
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.0 | cwd オプションは、file: プロトコルを使用する WHATWG URL オブジェクトにすることができます。 |
v10.10.0 | input オプションは、任意のTypedArray またはDataView にすることができます。 |
v8.8.0 | windowsHide オプションがサポートされました。 |
v8.0.0 | input オプションは、Uint8Array にすることができます。 |
v0.11.12 | v0.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
。
child_process.execSync()
メソッドは、子プロセスが完全に閉じるまでメソッドが返らない点を除いて、一般的にchild_process.exec()
と同じです。タイムアウトが発生してkillSignal
が送信された場合、メソッドはプロセスが完全に終了するまで返りません。子プロセスがSIGTERM
シグナルをインターセプトして処理し、終了しない場合、親プロセスは子プロセスが終了するまで待機します。
プロセスがタイムアウトするか、ゼロ以外の終了コードを持つ場合、このメソッドはエラーをスローします。Error
オブジェクトには、child_process.spawnSync()
からの結果全体が含まれます。
サニタイズされていないユーザー入力をこの関数に渡さないでください。シェルメタ文字を含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。
child_process.spawnSync(command[, args][, options])
[履歴]
バージョン | 変更 |
---|---|
v16.4.0, v14.18.0 | cwd オプションは file: プロトコルを使用する WHATWG URL オブジェクトにすることができます。 |
v10.10.0 | input オプションは任意の TypedArray または DataView にできるようになりました。 |
v8.8.0 | windowsHide オプションがサポートされるようになりました。 |
v8.0.0 | input オプションは Uint8Array にできるようになりました。 |
v5.7.0 | shell オプションがサポートされるようになりました。 |
v6.2.1, v4.5.0 | encoding オプションは明示的に buffer に設定できるようになりました。 |
v0.11.12 | v0.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
- 拡張: <EventEmitter>
ChildProcess
のインスタンスは、生成された子プロセスを表します。
ChildProcess
のインスタンスは、直接作成することを意図していません。代わりに、ChildProcess
のインスタンスを作成するには、child_process.spawn()
、child_process.exec()
、child_process.execFile()
、または child_process.fork()
メソッドを使用します。
イベント: 'close'
追加: v0.7.7
'close'
イベントは、プロセスが終了し、かつ 子プロセスの stdio ストリームが閉じられた後に発行されます。これは、複数のプロセスが同じ stdio ストリームを共有する可能性があるため、'exit'
イベントとは異なります。'close'
イベントは、'exit'
がすでに発行された後、または子プロセスの起動に失敗した場合は 'error'
が発行された後に常に発行されます。
const { spawn } = require('node:child_process')
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.on('close', code => {
console.log(`child process close all stdio with code ${code}`)
})
ls.on('exit', code => {
console.log(`child process exited with code ${code}`)
})
import { spawn } from 'node:child_process'
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', data => {
console.log(`stdout: ${data}`)
})
ls.on('close', code => {
console.log(`child process close all stdio with code ${code}`)
})
ls.on('exit', code => {
console.log(`child process exited with code ${code}`)
})
イベント: 'disconnect'
追加: v0.7.2
'disconnect'
イベントは、親プロセスで subprocess.disconnect()
メソッドを呼び出した後、または子プロセスで process.disconnect()
を呼び出した後に発生します。切断後、メッセージの送受信はできなくなり、subprocess.connected
プロパティは false
になります。
イベント: 'error'
err
<Error> エラー。
'error'
イベントは、次のいずれかの状況で発生します。
- プロセスを生成できなかった場合。
- プロセスを強制終了できなかった場合。
- 子プロセスへのメッセージ送信に失敗した場合。
- 子プロセスが
signal
オプションによって中断された場合。
'exit'
イベントは、エラー発生後に発生する場合としない場合があります。'exit'
イベントと 'error'
イベントの両方をリッスンする場合は、ハンドラー関数が複数回誤って呼び出されないように注意してください。
subprocess.kill()
および subprocess.send()
も参照してください。
イベント: 'exit'
追加: v0.1.90
'exit'
イベントは、子プロセスが終了した後に発生します。プロセスが終了した場合、code
はプロセスの最終終了コードであり、それ以外の場合は null
です。プロセスがシグナルの受信により終了した場合、signal
はシグナルの文字列名であり、それ以外の場合は null
です。いずれか一方は常に非 null
になります。
'exit'
イベントがトリガーされると、子プロセスの stdio ストリームがまだ開いている可能性があります。
Node.js は SIGINT
および SIGTERM
のシグナルハンドラーを設定し、Node.js プロセスはこれらのシグナルの受信によって直ちに終了することはありません。むしろ、Node.js は一連のクリーンアップアクションを実行し、その後、処理されたシグナルを再度発生させます。
waitpid(2)
を参照してください。
イベント: 'message'
追加: v0.5.9
message
<Object> パースされた JSON オブジェクトまたはプリミティブ値。sendHandle
<Handle> | <undefined>undefined
、またはnet.Socket
,net.Server
, またはdgram.Socket
オブジェクト。
'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'
イベントが発生しますが、bash
は some-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.connected
が false
の場合、メッセージを送受信することはできません。
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
を返します。
const { spawn } = require('node:child_process')
const grep = spawn('grep', ['ssh'])
grep.on('close', (code, signal) => {
console.log(`子プロセスはシグナル ${signal} を受信したため終了しました`)
})
// プロセスに SIGHUP を送信します。
grep.kill('SIGHUP')
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 では、子プロセスの親を強制終了しようとしても、子プロセスの子プロセスは終了しません。これは、シェルで新しいプロセスを実行する場合、または ChildProcess
の shell
オプションを使用する場合に発生する可能性が高くなります。
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)
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
'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
が発生します。
const { spawn } = require('node:child_process')
const grep = spawn('grep', ['ssh'])
console.log(`生成された子プロセス pid: ${grep.pid}`)
grep.stdin.end()
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()
を呼び出すと、子プロセスの削除された参照カウントが復元され、親プロセスは自身が終了する前に子プロセスの終了を待機することを強制します。
const { spawn } = require('node:child_process')
const process = require('node:process')
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
subprocess.ref()
import { spawn } from 'node:child_process'
import process from 'node:process'
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
subprocess.ref()
subprocess.send(message[, sendHandle[, options]][, callback])
[履歴]
バージョン | 変更 |
---|---|
v5.8.0 | options パラメーターと、特に keepOpen オプションがサポートされるようになりました。 |
v5.0.0 | このメソッドは、フロー制御のためにブール値を返すようになりました。 |
v4.0.0 | callback パラメーターがサポートされるようになりました。 |
v0.5.9 | 追加: v0.5.9 |
message
<Object>sendHandle
<Handle> | <undefined>undefined
、またはnet.Socket
、net.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'
イベントを介して受信できます。
メッセージはシリアル化と解析を経ます。結果として得られるメッセージは、最初に送信されたものと同じではない可能性があります。
たとえば、親スクリプトでは次のようになります。
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' })
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'
は次のようになります。
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 サーバーオブジェクトのハンドルを子プロセスに渡すために使用できます。
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)
})
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)
})
子プロセスは、次のようにサーバーオブジェクトを受信します。
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 つの子を生成します。
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)
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 番目の引数としてソケットハンドルを受け取ります。
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.stderr
はsubprocess.stdio[2]
のエイリアスです。どちらのプロパティも同じ値を参照します。
子プロセスが正常に spawn されなかった場合、subprocess.stderr
プロパティはnull
またはundefined
になることがあります。
subprocess.stdin
追加: v0.1.90
子プロセスの stdin
を表す Writable Stream
です。
子プロセスがすべての入力を読み込むのを待っている場合、このストリームが end()
を介して閉じられるまで子プロセスは続行されません。
子プロセスが stdio[0]
を 'pipe'
以外に設定して生成された場合、これは null
になります。
subprocess.stdin
は subprocess.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.stdin
、subprocess.stdout
、subprocess.stderr
としても利用できます。
次の例では、子プロセスの fd 1
(stdout) のみがパイプとして構成されているため、親の subprocess.stdio[1]
のみがストリームであり、配列内の他のすべての値は null
です。
const assert = require('node:assert')
const fs = require('node:fs')
const child_process = require('node:child_process')
const subprocess = child_process.spawn('ls', {
stdio: [
0, // 子プロセスに親の 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)
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.stdout
は subprocess.stdio[1]
のエイリアスです。両方のプロパティは同じ値を参照します。
const { spawn } = require('node:child_process')
const subprocess = spawn('ls')
subprocess.stdout.on('data', data => {
console.log(`Received chunk ${data}`)
})
import { spawn } from 'node:child_process'
const subprocess = spawn('ls')
subprocess.stdout.on('data', data => {
console.log(`Received chunk ${data}`)
})
子プロセスが正常に起動できなかった場合、subprocess.stdout
プロパティは null
または undefined
になることがあります。
subprocess.unref()
追加: v0.7.10
デフォルトでは、親プロセスは分離された子プロセスの終了を待ちます。特定の subprocess
が終了するのを親プロセスが待たないようにするには、subprocess.unref()
メソッドを使用します。そうすることで、親のイベントループは、子プロセスをその参照カウントに含めなくなり、子プロセスと親プロセスの間に確立された IPC チャネルがない限り、親が子プロセスとは独立して終了できるようになります。
const { spawn } = require('node:child_process')
const process = require('node:process')
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
import { spawn } from 'node:child_process'
import process from 'node:process'
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
})
subprocess.unref()
maxBuffer
と 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 のためのシリアライズメカニズムをサポートしています。これは一般的により強力で、BigInt
、Map
、Set
、ArrayBuffer
、TypedArray
、Buffer
、Error
、RegExp
など、より多くの組み込み JavaScript オブジェクト型をサポートします。
ただし、このフォーマットは JSON の完全なスーパーセットではなく、たとえば、このような組み込み型のオブジェクトに設定されたプロパティは、シリアライズステップを介して渡されません。さらに、渡されるデータの構造によっては、パフォーマンスが JSON と同等ではない場合があります。したがって、この機能は child_process.spawn()
または child_process.fork()
を呼び出すときに serialization
オプションを 'advanced'
に設定することでオプトインする必要があります。