子プロセス#

安定性: 2 - 安定

ソースコード: 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}`);
}); 

デフォルトでは、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() が行うことです)。いずれにしても、スクリプトのファイル名にスペースが含まれている場合は、引用符で囲む必要があります。

// 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)で呼び出されます。成功した場合、errornullになります。エラーの場合、errorErrorのインスタンスになります。 error.codeプロパティはプロセスの終了コードになります。慣例により、0以外の終了コードはエラーを示します。error.signalはプロセスを終了させたシグナルになります。

コールバックに渡されるstdoutstderrの引数には、子プロセスの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}`);
}); 

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

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

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

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

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

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

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です。

envundefined値は無視されます。

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

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

Windows 以外のプラットフォームでは、options.detachedtrue に設定されている場合、子プロセスは新しいプロセスグループとセッションのリーダーになります。子プロセスは、デタッチされているかどうかに関わらず、親が終了した後も実行を継続する可能性があります。詳細については、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.stdinsubprocess.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 を指定できます。値は次のいずれかです

  1. 'pipe': 子プロセスと親プロセスの間にパイプを作成します。パイプの親側の端は、親に subprocess.stdio[fd] として child_process オブジェクトのプロパティとして公開されます。fd 0、1、および 2 用に作成されたパイプは、それぞれ subprocess.stdinsubprocess.stdout および subprocess.stderr としても利用できます。これらは実際の Unix パイプではないため、子プロセスはそれらの記述子ファイル(例: /dev/fd/2/dev/stdout)を使用できません。

  2. 'overlapped': 'pipe' と同じですが、ハンドルに FILE_FLAG_OVERLAPPED フラグが設定されています。これは、子プロセスの stdio ハンドルでオーバーラップ I/O を行うために必要です。詳細については、ドキュメントを参照してください。これは Windows システム以外では 'pipe' とまったく同じです。

  3. 'ipc': 親と子の間でメッセージ/ファイル記述子を渡すための IPC チャネルを作成します。ChildProcess には、最大で 1 つの IPC stdio ファイル記述子を含めることができます。このオプションを設定すると、subprocess.send() メソッドが有効になります。子が Node.js プロセスの場合、IPC チャネルの存在により、process.send() および process.disconnect() メソッドと、'disconnect' および 'message' イベントが子の中で有効になります。

    process.send() 以外で IPC チャネル fd にアクセスしたり、Node.js インスタンスではない子プロセスで IPC チャネルを使用したりすることはサポートされていません。

  4. 'ignore': 子の fd を無視するように Node.js に指示します。Node.js は常に、スポーンするプロセスのために fd 0、1、および 2 を開きますが、fd を 'ignore' に設定すると、Node.js は /dev/null を開き、それを子プロセスにアタッチします。

  5. 'inherit': 親プロセスとの間で対応する stdio ストリームをパススルーします。最初の 3 つの位置では、それぞれ process.stdinprocess.stdout、および process.stderr と同等です。他の位置では、'ignore' と同等です。

  6. <Stream> オブジェクト: tty、ファイル、ソケット、またはパイプを参照する読み取り可能または書き込み可能なストリームを子プロセスと共有します。ストリームの基になるファイル記述子は、stdio 配列内のインデックスに対応する fd で子プロセス内で複製されます。ストリームには基になる記述子が必要です(ファイルストリームは 'open' イベントが発生するまで開始されません)。

  7. 正の整数: 整数値は、親プロセスで開かれているファイル記述子として解釈されます。これは、<Stream> オブジェクトを共有できるのと同じように、子プロセスと共有されます。ソケットの受け渡しは Windows ではサポートされていません。

  8. 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#

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

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

イベント: 'close'#

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

'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'#

'error' イベントは、次の場合に発生します。

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

エラーが発生した後、'exit' イベントが発生する場合と発生しない場合があります。'exit' イベントと 'error' イベントの両方をリッスンする場合、ハンドラー関数が複数回誤って呼び出されるのを防ぐ必要があります。

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

イベント: 'exit'#

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

'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' イベントが発生しますが、bashsome-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.connectedfalse の場合、メッセージを送受信することはできなくなります。

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 では、親プロセスを強制終了しようとしても、子プロセスのさらに子プロセスは終了しません。これは、シェルで新しいプロセスを実行したり、ChildProcessshell オプションを使用したりする場合に発生する可能性があります。

'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]()#

安定度: 1 - 実験的

'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.stderrsubprocess.stdio[2] のエイリアスです。両方のプロパティは同じ値を参照します。

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

subprocess.stdin#

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

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

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

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

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

subprocess.stdio#

stdio オプションで child_process.spawn() に渡され、値 'pipe' に設定されている位置に対応する、子プロセスへのパイプの疎な配列です。subprocess.stdio[0]subprocess.stdio[1]、および subprocess.stdio[2] は、それぞれ subprocess.stdinsubprocess.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.stdoutsubprocess.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 のシリアライゼーションメカニズムをサポートします。これは一般的に強力で、BigIntMapSetArrayBufferTypedArrayBufferErrorRegExp など、より多くの組み込み JavaScript オブジェクト型をサポートします。

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