Node.js v21.7.2 ドキュメント
- Node.js v21.7.2
-
► 目次
- 子プロセス
- 非同期プロセス生成
- 同期プロセス生成
- クラス:
ChildProcess
- イベント:
'close'
- イベント:
'disconnect'
- イベント:
'error'
- イベント:
'exit'
- イベント:
'message'
- イベント:
'spawn'
subprocess.channel
subprocess.connected
subprocess.disconnect()
subprocess.exitCode
subprocess.kill([signal])
subprocess[Symbol.dispose]()
subprocess.killed
subprocess.pid
subprocess.ref()
subprocess.send(message[, sendHandle[, options]][, callback])
subprocess.signalCode
subprocess.spawnargs
subprocess.spawnfile
subprocess.stderr
subprocess.stdin
subprocess.stdio
subprocess.stdout
subprocess.unref()
- イベント:
maxBuffer
と Unicode- シェルの要件
- Windows のデフォルトシェル
- 高度なシリアライズ
- 子プロセス
-
► インデックス
- アサーションテスト
- 非同期コンテキスト追跡
- Async Hooks
- Buffer
- C++ アドオン
- Node-API を使用した C/C++ アドオン
- C++ エンベダー API
- 子プロセス
- Cluster
- コマンドラインオプション
- Console
- Corepack
- Crypto
- Debugger
- 非推奨 API
- Diagnostics Channel
- DNS
- Domain
- エラー
- Events
- ファイルシステム
- グローバル
- HTTP
- HTTP/2
- HTTPS
- Inspector
- 国際化
- モジュール: CommonJS モジュール
- モジュール: ECMAScript モジュール
- モジュール:
node:module
API - モジュール: パッケージ
- Net
- OS
- Path
- Performance hooks
- 権限
- プロセス
- Punycode
- クエリ文字列
- Readline
- REPL
- Report
- 単一実行可能アプリケーション
- Stream
- String decoder
- テストランナー
- タイマー
- TLS/SSL
- トレースイベント
- TTY
- UDP/データグラム
- URL
- ユーティリティ
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- ワーカー スレッド
- Zlib
- ► その他のバージョン
- ► オプション
子プロセス#
ソースコード: 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(`child process exited with code ${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()
が行うことです)。いずれにしても、スクリプトのファイル名にスペースが含まれている場合は、引用符で囲む必要があります。
// On Windows Only...
const { spawn } = require('node:child_process');
const bat = spawn('cmd.exe', ['/c', 'my.bat']);
bat.stdout.on('data', (data) => {
console.log(data.toString());
});
bat.stderr.on('data', (data) => {
console.error(data.toString());
});
bat.on('exit', (code) => {
console.log(`Child exited with code ${code}`);
});
// OR...
const { exec, spawn } = require('node:child_process');
exec('my.bat', (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(stdout);
});
// Script with spaces in the filename:
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])
#
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)
のsetuid(2)
を参照)。gid
<number> プロセスのグループ ID を設定します (setgid(2)
の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');
// Double quotes are used so that the space in the path is not interpreted as
// a delimiter of multiple arguments.
exec('echo "The \\$HOME variable is $HOME"');
// The $HOME variable is escaped in the first instance, but not in the second.
サニタイズされていないユーザー入力をこの関数に渡さないでください。シェルメタ文字を含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。
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}`);
});
timeout
が0
より大きい場合、親は、子プロセスがtimeout
ミリ秒よりも長く実行された場合、killSignal
プロパティ(デフォルトは'SIGTERM'
)で識別されるシグナルを送信します。
exec(3)
POSIXシステムコールとは異なり、child_process.exec()
は既存のプロセスを置き換えるのではなく、シェルを使用してコマンドを実行します。
このメソッドがutil.promisify()
されたバージョンとして呼び出された場合、stdout
とstderr
プロパティを持つObject
のPromise
を返します。返されたChildProcess
インスタンスは、child
プロパティとしてPromise
に添付されます。エラーが発生した場合(0以外の終了コードにつながるエラーを含む)、拒否されたpromiseが返され、コールバックで与えられたものと同じerror
オブジェクトが返されますが、2つの追加プロパティ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();
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();
child_process.execFile(file[, args][, options][, callback])
#
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)
のsetuid(2)
を参照)。gid
<number> プロセスのグループ ID を設定します (setgid(2)
の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);
});
コールバックに渡されるstdout
とstderr
の引数には、子プロセスのstdoutとstderrの出力が含まれます。デフォルトでは、Node.jsは出力をUTF-8としてデコードし、文字列をコールバックに渡します。encoding
オプションを使用して、stdoutおよびstderr出力のデコードに使用される文字エンコーディングを指定できます。 encoding
が'buffer'
であるか、認識されない文字エンコーディングである場合、代わりにBuffer
オブジェクトがコールバックに渡されます。
このメソッドがutil.promisify()
されたバージョンとして呼び出された場合、stdout
とstderr
プロパティを持つObject
のPromise
を返します。返されたChildProcess
インスタンスは、child
プロパティとしてPromise
に添付されます。エラーが発生した場合(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();
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();
child_process.fork(modulePath[, args][, options])
#
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)
のsetgid(2)
を参照)。serialization
<string> プロセス間でメッセージを送信するために使用されるシリアル化の種類を指定します。可能な値は'json'
と'advanced'
です。詳細については、高度なシリアル化を参照してください。デフォルト:'json'
。signal
<AbortSignal> AbortSignalを使用して子プロセスを閉じることができます。killSignal
<string> | <integer> タイムアウトまたは中止シグナルによって生成されたプロセスが強制終了されるときに使用されるシグナル値。デフォルト:'SIGTERM'
。silent
<boolean>true
の場合、子のstdin、stdout、およびstderrは親にパイプされます。それ以外の場合、親から継承されます。child_process.spawn()
のstdio
の'pipe'
および'inherit'
オプションを参照してください。詳細については、デフォルト:false
。stdio
<Array> | <string>child_process.spawn()
のstdio
を参照してください。このオプションが提供されると、silent
が上書きされます。配列バリアントを使用する場合、値が'ipc'
の項目を1つだけ含める必要があります。そうしないと、エラーがスローされます。たとえば、[0, 1, 2, 'ipc']
などです。uid
<number> プロセスのユーザー ID を設定します (setuid(2)
の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
になります。
if (process.argv[2] === 'child') {
setTimeout(() => {
console.log(`Hello from ${process.argv[2]}!`);
}, 1_000);
} else {
const { fork } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const child = fork(__filename, ['child'], { signal });
child.on('error', (err) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process
}
child_process.spawn(command[, args][, options])
#
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)
のsetuid(2)
を参照)。gid
<number> プロセスのグループ ID を設定します (setgid(2)
の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}`);
});
例: 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}`);
}
});
spawn
の失敗をチェックする例
const { spawn } = require('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) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process
options.detached
#
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 subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
});
subprocess.unref();
あるいは、子プロセスの出力をファイルにリダイレクトすることもできます
const fs = require('node:fs');
const { spawn } = require('node:child_process');
const out = fs.openSync('./out.log', 'a');
const err = fs.openSync('./out.log', 'a');
const subprocess = spawn('prg', [], {
detached: true,
stdio: [ 'ignore', out, err ],
});
subprocess.unref();
options.stdio
#
options.stdio
オプションは、親プロセスと子プロセスの間に確立されるパイプを構成するために使用されます。デフォルトでは、子の stdin、stdout、および stderr は、subprocess.stdin
、subprocess.stdout
、および subprocess.stderr
ストリームにリダイレクトされます。ChildProcess
オブジェクト上。これは、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 を指定できます。値は次のいずれかです
-
'pipe'
: 子プロセスと親プロセスの間にパイプを作成します。パイプの親側の端は、親にsubprocess.stdio[fd]
としてchild_process
オブジェクトのプロパティとして公開されます。fd 0、1、および 2 用に作成されたパイプは、それぞれsubprocess.stdin
、subprocess.stdout
およびsubprocess.stderr
としても利用できます。これらは実際の Unix パイプではないため、子プロセスはそれらの記述子ファイル(例:/dev/fd/2
や/dev/stdout
)を使用できません。 -
'overlapped'
:'pipe'
と同じですが、ハンドルにFILE_FLAG_OVERLAPPED
フラグが設定されています。これは、子プロセスの stdio ハンドルでオーバーラップ I/O を行うために必要です。詳細については、ドキュメントを参照してください。これは Windows システム以外では'pipe'
とまったく同じです。 -
'ipc'
: 親と子の間でメッセージ/ファイル記述子を渡すための IPC チャネルを作成します。ChildProcess
には、最大で 1 つの IPC stdio ファイル記述子を含めることができます。このオプションを設定すると、subprocess.send()
メソッドが有効になります。子が Node.js プロセスの場合、IPC チャネルの存在により、process.send()
およびprocess.disconnect()
メソッドと、'disconnect'
および'message'
イベントが子の中で有効になります。process.send()
以外で IPC チャネル fd にアクセスしたり、Node.js インスタンスではない子プロセスで IPC チャネルを使用したりすることはサポートされていません。 -
'ignore'
: 子の fd を無視するように Node.js に指示します。Node.js は常に、スポーンするプロセスのために fd 0、1、および 2 を開きますが、fd を'ignore'
に設定すると、Node.js は/dev/null
を開き、それを子プロセスにアタッチします。 -
'inherit'
: 親プロセスとの間で対応する stdio ストリームをパススルーします。最初の 3 つの位置では、それぞれprocess.stdin
、process.stdout
、およびprocess.stderr
と同等です。他の位置では、'ignore'
と同等です。 -
<Stream> オブジェクト: tty、ファイル、ソケット、またはパイプを参照する読み取り可能または書き込み可能なストリームを子プロセスと共有します。ストリームの基になるファイル記述子は、
stdio
配列内のインデックスに対応する fd で子プロセス内で複製されます。ストリームには基になる記述子が必要です(ファイルストリームは'open'
イベントが発生するまで開始されません)。 -
正の整数: 整数値は、親プロセスで開かれているファイル記述子として解釈されます。これは、<Stream> オブジェクトを共有できるのと同じように、子プロセスと共有されます。ソケットの受け渡しは Windows ではサポートされていません。
-
null
,undefined
: デフォルト値を使用します。stdio fd 0、1、および 2(つまり、stdin、stdout、および stderr)の場合、パイプが作成されます。fd 3 以降の場合、デフォルトは'ignore'
です。
const { spawn } = require('node:child_process');
// Child will use parent's stdios.
spawn('prg', [], { stdio: 'inherit' });
// Spawn child sharing only stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });
// Open an extra fd=4, to interact with programs presenting a
// startd-style interface.
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])
#
file
<string> 実行する実行可能ファイルの名前またはパス。args
<string[]> 文字列引数のリスト。options
<Object>cwd
<string> | <URL> 子プロセスの現在の作業ディレクトリ。input
<string> | <Buffer> | <TypedArray> | <DataView> スポーンされたプロセスに stdin として渡される値。stdio[0]
が'pipe'
に設定されている場合、この値を指定するとstdio[0]
が上書きされます。stdio
<string> | <Array> 子の stdio 構成。stdio
が指定されていない限り、デフォルトではstderr
は親プロセスの stderr に出力されます。デフォルト:'pipe'
。env
<Object> 環境キーと値のペア。デフォルト:process.env
。uid
<number> プロセスのユーザー ID を設定します (setuid(2)
のsetuid(2)
を参照)。gid
<number> プロセスのグループ ID を設定します (setgid(2)
のsetgid(2)
を参照)。timeout
<number> プロセスの実行が許可される最大時間(ミリ秒単位)。デフォルト:undefined
。killSignal
<string> | <integer> スポーンされたプロセスが kill されるときに使用されるシグナル値。デフォルト:'SIGTERM'
。maxBuffer
<number> stdout または stderr で許可される最大データ量(バイト単位)。これを超えると、子プロセスは終了されます。maxBuffer
と Unicode の注意点 を参照してください。デフォルト:1024 * 1024
。encoding
<string> すべての標準入出力に使用するエンコーディング。デフォルト:'buffer'
。windowsHide
<boolean> Windowsシステムで通常作成されるサブプロセスのコンソールウィンドウを非表示にします。デフォルト:false
。shell
<boolean> | <string>true
の場合、シェル内でcommand
を実行します。 Unixでは'/bin/sh'
を使用し、Windowsではprocess.env.ComSpec
を使用します。別のシェルを文字列として指定できます。シェルの要件およびデフォルトのWindowsシェルを参照してください。デフォルト:false
(シェルなし)。
- 戻り値: <Buffer> | <string> コマンドからの標準出力。
child_process.execFileSync()
メソッドは、一般的に child_process.execFile()
と同じですが、子プロセスが完全に終了するまでメソッドが返らない点が異なります。タイムアウトが発生し、killSignal
が送信された場合、プロセスが完全に終了するまでメソッドは返りません。
子プロセスが SIGTERM
シグナルをインターセプトして処理し、終了しない場合でも、親プロセスは子プロセスが終了するまで待機します。
プロセスがタイムアウトするか、ゼロ以外の終了コードを持つ場合、このメソッドは Error
をスローします。このエラーには、基になる child_process.spawnSync()
の結果がすべて含まれます。
shell
オプションが有効になっている場合、サニタイズされていないユーザー入力をこの関数に渡さないでください。シェルメタ文字を含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。
child_process.execSync(command[, options])
#
command
<string> 実行するコマンド。options
<Object>cwd
<string> | <URL> 子プロセスの現在の作業ディレクトリ。input
<string> | <Buffer> | <TypedArray> | <DataView> スポーンされたプロセスに stdin として渡される値。stdio[0]
が'pipe'
に設定されている場合、この値を指定するとstdio[0]
が上書きされます。stdio
<string> | <Array> 子の 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> スポーンされたプロセスが kill されるときに使用されるシグナル値。デフォルト:'SIGTERM'
。maxBuffer
<number> stdout または stderr で許可される最大データ量(バイト単位)。これを超えると、子プロセスは終了し、すべての出力が切り捨てられます。「maxBuffer
と Unicode」にある注意点を確認してください。デフォルト:1024 * 1024
。encoding
<string> すべての標準入出力に使用するエンコーディング。デフォルト:'buffer'
。windowsHide
<boolean> Windowsシステムで通常作成されるサブプロセスのコンソールウィンドウを非表示にします。デフォルト:false
。
- 戻り値: <Buffer> | <string> コマンドからの標準出力。
child_process.execSync()
メソッドは、一般的に child_process.exec()
と同じですが、子プロセスが完全に終了するまでメソッドが返らない点が異なります。タイムアウトが発生し、killSignal
が送信された場合、プロセスが完全に終了するまでメソッドは返りません。子プロセスが SIGTERM
シグナルをインターセプトして処理し、終了しない場合、親プロセスは子プロセスが終了するまで待機します。
プロセスがタイムアウトするか、ゼロ以外の終了コードを持つ場合、このメソッドは例外をスローします。Error
オブジェクトには、child_process.spawnSync()
からの結果がすべて含まれます。
サニタイズされていないユーザー入力をこの関数に渡さないでください。シェルメタ文字を含む入力は、任意のコマンド実行をトリガーするために使用される可能性があります。
child_process.spawnSync(command[, args][, options])
#
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> 子プロセスの標準入出力構成。デフォルト:'pipe'
。env
<Object> 環境キーと値のペア。デフォルト:process.env
。uid
<number> プロセスのユーザー ID を設定します (setuid(2)
のsetuid(2)
を参照)。gid
<number> プロセスのグループ ID を設定します (setgid(2)
のsetgid(2)
を参照)。timeout
<number> プロセスの実行が許可される最大時間(ミリ秒単位)。デフォルト:undefined
。killSignal
<string> | <integer> スポーンされたプロセスが kill されるときに使用されるシグナル値。デフォルト:'SIGTERM'
。maxBuffer
<number> stdout または stderr で許可される最大データ量(バイト単位)。これを超えると、子プロセスは終了し、すべての出力が切り捨てられます。「maxBuffer
と Unicode」にある注意点を確認してください。デフォルト:1024 * 1024
。encoding
<string> すべての標準入出力に使用するエンコーディング。デフォルト:'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> 標準出力からの結果の配列。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
#
- 拡張: <EventEmitter>
ChildProcess
のインスタンスは、生成された子プロセスを表します。
ChildProcess
のインスタンスを直接作成することは意図されていません。代わりに、child_process.spawn()
、child_process.exec()
、child_process.execFile()
、または child_process.fork()
メソッドを使用して ChildProcess
のインスタンスを作成してください。
イベント: 'close'
#
'close'
イベントは、プロセスが終了し、子プロセスの標準入出力ストリームが閉じられた後に発生します。これは、複数のプロセスが同じ標準入出力ストリームを共有する可能性があるため、'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}`);
});
イベント: 'disconnect'
#
'disconnect'
イベントは、親プロセスで subprocess.disconnect()
メソッドを呼び出すか、子プロセスで process.disconnect()
を呼び出した後に発生します。切断後はメッセージの送受信ができなくなり、subprocess.connected
プロパティが false
になります。
イベント: 'error'
#
err
<Error> エラー。
'error'
イベントは、次の場合に発生します。
- プロセスを生成できなかった場合。
- プロセスを強制終了できなかった場合。
- 子プロセスへのメッセージ送信に失敗した場合。
signal
オプションによって子プロセスが中断された場合。
エラーが発生した後、'exit'
イベントが発生する場合と発生しない場合があります。'exit'
イベントと 'error'
イベントの両方をリッスンする場合、ハンドラー関数が複数回誤って呼び出されるのを防ぐ必要があります。
subprocess.kill()
および subprocess.send()
も参照してください。
イベント: 'exit'
#
'exit'
イベントは、子プロセスが終了した後に発生します。プロセスが終了した場合、code
はプロセスの最終的な終了コードであり、それ以外の場合は null
です。プロセスがシグナルの受信によって終了した場合、signal
はシグナルの文字列名であり、それ以外の場合は null
です。どちらか一方が常に非 null
になります。
'exit'
イベントがトリガーされると、子プロセスの標準入出力ストリームがまだ開いている可能性があります。
Node.js は、SIGINT
および SIGTERM
のシグナルハンドラーを確立します。Node.js プロセスは、これらのシグナルの受信によってすぐには終了しません。代わりに、Node.js は一連のクリーンアップアクションを実行し、処理されたシグナルを再度発生させます。
waitpid(2)
を参照してください。
イベント: 'message'
#
message
<Object> パースされた JSON オブジェクトまたはプリミティブ値。sendHandle
<Handle>net.Socket
またはnet.Server
オブジェクト、または undefined。
'message'
イベントは、子プロセスが process.send()
を使用してメッセージを送信するときにトリガーされます。
メッセージはシリアル化とパースを通過します。結果として得られるメッセージは、最初に送信されたものと同じではない可能性があります。
子プロセスを生成するときに serialization
オプションが 'advanced'
に設定されている場合、message
引数には JSON で表現できないデータを含めることができます。詳細については、高度なシリアル化 を参照してください。
イベント: 'spawn'
#
'spawn'
イベントは、子プロセスが正常に生成された後に一度だけ発生します。子プロセスが正常に生成されない場合、'spawn'
イベントは発生せず、代わりに 'error'
イベントが発生します。
発生した場合、'spawn'
イベントは、他のすべてのイベントよりも前に、stdout
または stderr
を介してデータを受信する前に発生します。
'spawn'
イベントは、生成されたプロセス内でエラーが発生したかどうかに関係なく発生します。たとえば、bash some-command
が正常に生成された場合、'spawn'
イベントが発生しますが、bash
が some-command
の生成に失敗する可能性があります。この注意点は、{ shell: true }
を使用する場合にも適用されます。
subprocess.channel
#
- <Object> 子プロセスへの IPC チャネルを表すパイプ。
subprocess.channel
プロパティは、子プロセスの IPC チャネルへの参照です。IPC チャネルが存在しない場合、このプロパティは undefined
です。
subprocess.channel.ref()
#
このメソッドは、以前に .unref()
が呼び出された場合に、IPC チャネルが親プロセスのイベントループを継続させるようにします。
subprocess.channel.unref()
#
このメソッドは、IPC チャネルが親プロセスのイベントループを継続させないようにし、チャネルが開いている間でも終了できるようにします。
subprocess.connected
#
- <boolean>
subprocess.disconnect()
が呼び出された後、false
に設定されます。
subprocess.connected
プロパティは、子プロセスとの間でメッセージを送受信できるかどうかを示します。subprocess.connected
が false
の場合、メッセージを送受信することはできなくなります。
subprocess.disconnect()
#
親プロセスと子プロセス間の 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])
#
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(
`child process terminated due to receipt of signal ${signal}`);
});
// Send SIGHUP to process.
grep.kill('SIGHUP');
ChildProcess
オブジェクトは、シグナルを配信できない場合に 'error'
イベントを発生させる可能性があります。すでに終了している子プロセスにシグナルを送信することはエラーではありませんが、予期せぬ結果を招く可能性があります。特に、プロセス識別子 (PID) が別のプロセスに再割り当てされている場合、シグナルはそのプロセスに配信され、予期しない結果になる可能性があります。
この関数は kill
と呼ばれていますが、子プロセスに配信されるシグナルが実際にプロセスを終了させるとは限りません。
詳細については、kill(2)
を参照してください。
Windows では POSIX シグナルが存在しないため、signal
引数は無視され、プロセスは強制的に急停止されます ('SIGKILL'
と同様)。詳細については、シグナルイベントを参照してください。
Linux では、親プロセスを強制終了しようとしても、子プロセスのさらに子プロセスは終了しません。これは、シェルで新しいプロセスを実行したり、ChildProcess
の shell
オプションを使用したりする場合に発生する可能性があります。
'use strict';
const { spawn } = require('node:child_process');
const subprocess = spawn(
'sh',
[
'-c',
`node -e "setInterval(() => {
console.log(process.pid, 'is alive')
}, 500);"`,
], {
stdio: ['inherit', 'inherit', 'inherit'],
},
);
setTimeout(() => {
subprocess.kill(); // Does not terminate the Node.js process in the shell.
}, 2000);
subprocess[Symbol.dispose]()
#
'SIGTERM'
を指定して subprocess.kill()
を呼び出します。
subprocess.killed
#
- <boolean>
subprocess.kill()
が子プロセスにシグナルを正常に送信するために使用された後、true
に設定されます。
subprocess.killed
プロパティは、子プロセスが subprocess.kill()
からシグナルを正常に受信したかどうかを示します。killed
プロパティは、子プロセスが終了したことを示すものではありません。
subprocess.pid
#
子プロセスのプロセス識別子 (PID) を返します。エラーにより子プロセスの生成に失敗した場合、値は undefined
になり、error
が発生します。
const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);
console.log(`Spawned child pid: ${grep.pid}`);
grep.stdin.end();
subprocess.ref()
#
subprocess.unref()
を呼び出した後に subprocess.ref()
を呼び出すと、子プロセスの削除された参照カウントが復元され、親プロセスは自身が終了する前に子が終了するのを強制的に待機します。
const { spawn } = require('node:child_process');
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
});
subprocess.unref();
subprocess.ref();
subprocess.send(message[, sendHandle[, options]][, callback])
#
message
<Object>sendHandle
<Handle>options
<Object>options
引数は、存在する場合、特定のタイプのハンドル送信をパラメーター化するために使用されるオブジェクトです。options
は次のプロパティをサポートします。keepOpen
<boolean>net.Socket
のインスタンスを渡す際に使用できる値。true
の場合、ソケットは送信プロセスで開いたままになります。デフォルト:false
。
callback
<Function>- 戻り値: <boolean>
親と子との間で IPC チャネルが確立されている場合 (つまり、child_process.fork()
を使用する場合)、subprocess.send()
メソッドを使用して子プロセスにメッセージを送信できます。子プロセスが Node.js インスタンスの場合、これらのメッセージは 'message'
イベントを介して受信できます。
メッセージはシリアル化とパースを通過します。結果として得られるメッセージは、最初に送信されたものと同じではない可能性があります。
例えば、親スクリプトでは
const cp = require('node:child_process');
const n = cp.fork(`${__dirname}/sub.js`);
n.on('message', (m) => {
console.log('PARENT got message:', m);
});
// Causes the child to print: CHILD got message: { hello: 'world' }
n.send({ hello: 'world' });
そして、子スクリプト 'sub.js'
は次のようになります。
process.on('message', (m) => {
console.log('CHILD got message:', m);
});
// Causes the parent to print: 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 番目の引数としてオブジェクトを受け取ります。ソケットで受信およびバッファリングされたデータは、子には送信されません。
オプションの callback
は、メッセージが送信された後、子が受信する前に呼び出される関数です。この関数は、成功した場合は null
を、失敗した場合は Error
オブジェクトを引数として 1 つ受け取ります。
callback
関数が提供されず、メッセージを送信できない場合、ChildProcess
オブジェクトによって 'error'
イベントが発生します。これは、例えば、子プロセスがすでに終了している場合に発生する可能性があります。
subprocess.send()
は、チャネルが閉じている場合、または送信されていないメッセージのバックログが、それ以上送信することが賢明ではないしきい値を超えた場合に false
を返します。それ以外の場合、メソッドは true
を返します。callback
関数を使用して、フロー制御を実装できます。
例: サーバーオブジェクトの送信#
sendHandle
引数は、例えば、以下の例に示すように、TCP サーバーオブジェクトのハンドルを子プロセスに渡すために使用できます。
const subprocess = require('node:child_process').fork('subprocess.js');
// Open up the server object and send the handle.
const server = require('node:net').createServer();
server.on('connection', (socket) => {
socket.end('handled by parent');
});
server.listen(1337, () => {
subprocess.send('server', server);
});
すると、子はサーバーオブジェクトを次のように受信します。
process.on('message', (m, server) => {
if (m === 'server') {
server.on('connection', (socket) => {
socket.end('handled by child');
});
}
});
サーバーが親と子の間で共有されると、一部の接続は親によって処理され、一部の接続は子によって処理される可能性があります。
上記の例では、node:net
モジュールを使用して作成されたサーバーを使用していますが、node:dgram
モジュールサーバーは、'connection'
の代わりに 'message'
イベントをリッスンし、server.listen()
の代わりに server.bind()
を使用する点を除き、まったく同じワークフローを使用します。ただし、これは Unix プラットフォームでのみサポートされています。
例: ソケットオブジェクトの送信#
同様に、sendHandler
引数を使用して、ソケットのハンドルを子プロセスに渡すことができます。以下の例では、それぞれ「通常」または「特別」優先度で接続を処理する 2 つの子プロセスを生成します。
const { fork } = require('node:child_process');
const normal = fork('subprocess.js', ['normal']);
const special = fork('subprocess.js', ['special']);
// Open up the server and send sockets to child. Use pauseOnConnect to prevent
// the sockets from being read before they are sent to the child process.
const server = require('node:net').createServer({ pauseOnConnect: true });
server.on('connection', (socket) => {
// If this is special priority...
if (socket.remoteAddress === '74.125.127.100') {
special.send('socket', socket);
return;
}
// This is normal priority.
normal.send('socket', socket);
});
server.listen(1337);
subprocess.js
は、イベントコールバック関数に渡される 2 番目の引数としてソケットハンドルを受信します。
process.on('message', (m, socket) => {
if (m === 'socket') {
if (socket) {
// Check that the client socket exists.
// It is possible for the socket to be closed between the time it is
// sent and the time it is received in the child process.
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
#
子プロセスの stderr
を表す Readable Stream
です。
子が stdio[2]
が 'pipe'
以外に設定されて生成された場合、これは null
になります。
subprocess.stderr
は subprocess.stdio[2]
のエイリアスです。両方のプロパティは同じ値を参照します。
子プロセスを正常に生成できなかった場合、subprocess.stderr
プロパティは null
または undefined
になる可能性があります。
subprocess.stdin
#
子プロセスの stdin
を表す Writable Stream
です。
子プロセスがすべての入力を読み込むのを待機している場合、このストリームが end()
を介して閉じられるまで子プロセスは続行しません。
子プロセスが stdio[0]
が 'pipe'
以外に設定されてspawnされた場合、これは null
になります。
subprocess.stdin
は subprocess.stdio[0]
のエイリアスです。両方のプロパティは同じ値を参照します。
子プロセスが正常にspawnできなかった場合、subprocess.stdin
プロパティは null
または undefined
になる可能性があります。
subprocess.stdio
#
stdio
オプションで child_process.spawn()
に渡され、値 '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, // Use parent's stdin for child.
'pipe', // Pipe child's stdout to parent.
fs.openSync('err.out', 'w'), // Direct child's stderr to a file.
],
});
assert.strictEqual(subprocess.stdio[0], null);
assert.strictEqual(subprocess.stdio[0], subprocess.stdin);
assert(subprocess.stdout);
assert.strictEqual(subprocess.stdio[1], subprocess.stdout);
assert.strictEqual(subprocess.stdio[2], null);
assert.strictEqual(subprocess.stdio[2], subprocess.stderr);
子プロセスが正常にspawnできなかった場合、subprocess.stdio
プロパティは undefined
になる可能性があります。
subprocess.stdout
#
子プロセスの stdout
を表す Readable Stream
です。
子プロセスが stdio[1]
が 'pipe'
以外に設定されてspawnされた場合、これは 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}`);
});
子プロセスが正常にspawnできなかった場合、subprocess.stdout
プロパティは null
または undefined
になる可能性があります。
subprocess.unref()
#
デフォルトでは、親はデタッチされた子が終了するのを待ちます。親が特定の subprocess
の終了を待機しないようにするには、subprocess.unref()
メソッドを使用します。これにより、親のイベントループは参照カウントに子を含めなくなり、子と親の間に確立された IPC チャネルがない限り、親は子とは独立して終了できます。
const { spawn } = require('node:child_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'
へのパスが含まれている必要があると指定していますが、子プロセスは必ずしも同じ要件に従うわけではありません。したがって、シェルをspawnできる child_process
関数では、process.env.ComSpec
が利用できない場合、フォールバックとして 'cmd.exe'
が使用されます。
高度なシリアライズ#
子プロセスは、node:v8
モジュールのシリアライゼーション API に基づく、HTML 構造化クローンアルゴリズム に基づく IPC のシリアライゼーションメカニズムをサポートします。これは一般的に強力で、BigInt
、Map
、Set
、ArrayBuffer
、TypedArray
、Buffer
、Error
、RegExp
など、より多くの組み込み JavaScript オブジェクト型をサポートします。
ただし、この形式は JSON の完全なスーパーセットではなく、たとえば、そのような組み込み型のオブジェクトに設定されたプロパティは、シリアライゼーションステップを介して渡されません。さらに、パフォーマンスは、渡されるデータの構造に応じて、JSON のパフォーマンスと同等ではない場合があります。したがって、この機能を使用するには、child_process.spawn()
または child_process.fork()
を呼び出すときに serialization
オプションを 'advanced'
に設定することでオプトインする必要があります。