Node.js v0.11.11 マニュアル & ドキュメンテーション
Table of Contents
Child Process#
Stability: 3 - Stable
Nodeは child_process
モジュールを通じて、3 方向の popen(3)
機能を提供します。
これは完全にノンブロッキングな方法で子プロセスの stdin
、stdout
、
そして stderr
を通じたデータストリームを実現します。
(いくつかのプログラムは内部的にバッファリングされた I/O を使うことに
注意してください。それは node.js には影響しませんが、
子プロセスに送ったデータがすぐに消費されるとは限らないことを意味します)。
子プロセスの生成は require('child_process').spawn()
または
require('child_process').fork()
を使います。
それぞれの意味論は以下で説明するようにわずかに異なります。
Class: ChildProcess#
ChildProcess
は EventEmitter です。
子プロセスは常に 3 本のストリームと関連づけられています。
child.stdin
、child.stdout
、そして child.stderr
です。
それらは親プロセスの標準入出力ストリームを共有するかもしれませんし、
独立したストリームオブジェクトにパイプでつながれているかもしれません。
Event: 'error'#
err
{Error Object} エラー。
次の場合に生成されます:
- プロセスを起動できなかった、または
- プロセスを殺すことができなかった、または
- 何らかの理由で子プロセスにメッセージを送信することが失敗した。
エラーが発生した後、'exit'
イベントは生成されることもあれば
されないこともあることに注意してください。
もし両方のイベントを監視するなら、リスナ関数は2回呼び出されることに備えることを
忘れないでください。
ChildProcess#kill()
および
ChildProcess#send()
も参照してください。
Event: 'exit'#
code
{Number} 通常に終了した場合は終了コード。signal
{String} 親プロセスによって終了させられた場合は、 子プロセスを終了するために送られたシグナル。
このイベントは子プロセスが終了した後で生成されます。
プロセスが普通に終了した場合、code
はプロセスの終了コードです。
それ以外の場合は null
です。
プロセスがシグナルを受け取って終了した場合、signal
は文字列によるシグナルの名前です。
それ以外の場合は null
です。
子プロセスの標準入出力ストリームはオープンしたままになっているかも しれないことに注意してください。
また、Node が 'SIGINT' および
'SIGTERM' に対するシグナルハンドラを
確立するため、子プロセスがそれらのシグナルを受けとって終了しても、
signal` にはそれらのシグナルの名前が設定されないことに注意してください。
waitpid(2)
を参照してください。
Event: 'close'#
code
{Number} 普通に終了した場合は、その終了コード。signal
{String} 親プロセスによって殺された場合は、 子プロセスを殺すために渡されたシグナル。
このイベントは、子プロセスの標準入出力ストリームが全て終了した場合に
生成されます。
複数のプロセスが同じ標準入出力ストリームを共有するかもしれないので、
これは 'exit'
とは明確に異なります。
Event: 'disconnect'#
このイベントは、親プロセスまたは子プロセスで .disconnect()
メソッドが
呼び出された場合に生成されます。
切断の後では、プロセス間でメッセージを送信することはできず、
.connected
プロパティは false
になります。
Event: 'message'#
message
{Object} 解析済みの JSON オブジェクトまたはプリミティブ値sendHandle
{Handle object} ソケットまたはサーバオブジェクト
.send(message, [sendHandle])
によって送信されたメッセージは 'message'
イベントによって取得できます。
child.stdin#
- Stream object
子プロセスの stdin
を表現する Writable Stream
です。
多くの場合、end()
を通じてこのストリームを閉じると子プロセスが終了する原因となります。
子プロセスの標準入出力が親プロセスと共有されている場合は設定されません。
child.stdout#
- Stream object
子プロセスの stdout
を表現する Readable Stream
です。
子プロセスの標準入出力が親プロセスと共有されている場合は設定されません。
child.stderr#
- Stream object
子プロセスの stderr
を表現する Readable Stream
です。
子プロセスの標準入出力が親プロセスと共有されている場合は設定されません。
child.pid#
- Integer
子プロセスの PID です。
例:
var spawn = require('child_process').spawn,
grep = spawn('grep', ['ssh']);
console.log('Spawned child pid: ' + grep.pid);
grep.stdin.end();
child.connected#
- {Boolean}
.disconnect' が呼び出されると
false` に設定される
.connected
が false
の場合、メッセージを送信することはできません。
child.kill([signal])#
signal
String
子プロセスにシグナルを送ります。
引数が与えられない場合、子プロセスには 'SIGTERM'
が送られます。
利用可能なシグナルの一覧は signal(7)
を参照してください。
var spawn = require('child_process').spawn,
grep = spawn('grep', ['ssh']);
grep.on('close', function (code, signal) {
console.log('child process terminated due to receipt of signal '+signal);
});
// send SIGHUP to process
grep.kill('SIGHUP');
シグナルを送ることができなかった場合は 'error'
イベントが
生成されるかもしれません。
既に終了した子プロセスへシグナルを送信してもエラーにはならず、
予想しない結果になるかもしれません:
PID (プロセス ID) が他のプロセスに再割り当てされると、
シグナルはそのプロセスに送信されてしまいます。
それで何が起こるかは誰にも予想できません。
この関数は kill
と呼ばれるものの、
子プロセスに届けられるシグナルが実際には子プロセスを殺さないかもしれないことに注意してください。
kill
はただプロセスにシグナルを送るだけです。
kill(2)
を参照してください。
child.send(message, [sendHandle])#
message
ObjectsendHandle
Handle object
child_process.fork()
を使うと、child.send(message, [sendHandle])
を
使って子プロセスにメッセージを送信し、子プロセスではそれを 'message'
イベントによって受け取ることができます。
例:
var cp = require('child_process');
var n = cp.fork(__dirname + '/sub.js');
n.on('message', function(m) {
console.log('PARENT got message:', m);
});
n.send({ hello: 'world' });
子プロセスの 'sub.js'
は次のようになります:
process.on('message', function(m) {
console.log('CHILD got message:', m);
});
process.send({ foo: 'bar' });
子プロセスでは process
オブジェクトは send()
メソッドを持ち、
そのチャネル上でメッセージを受信するたびにイベントを生成します。
親プロセスと子プロセスのいずれにおいても、send()
メソッドは同期的です -
データの大きな塊を送信することは推奨されません
(代わりにパイプを使うことが出来ます、
child_process.spawn
を参照してください)。
特別なケースとして、{cmd: 'NODE_foo'}
のようなメッセージを
送信する場合があります。
cmd
プロパティが接頭辞 NODE_
を含む全てのメッセージは node のコアで
使われる内部的なメッセージであるため、'message'
イベントを生成しません。
この接頭辞を含むメッセージは 'internalMessage'
イベントを生成しますが、
それを使用すべきではありません。それは保証なしに変更される可能性があります。
child.send()
の sendHandle
オプションは TCP サーバまたは
ソケットオブジェクトを他のプロセスに送信するためのものです。
子プロセスはそれを 'message'
イベントの第 2 引数として受信します。
たとえば子プロセスが既に終了した場合など、メッセージを送信できなかった場合は
'error'
イベントが生成されます。
Example: sending server object#
サーバを送信する例:
var child = require('child_process').fork('child.js');
// Open up the server object and send the handle.
var server = require('net').createServer();
server.on('connection', function (socket) {
socket.end('handled by parent');
});
server.listen(1337, function() {
child.send('server', server);
});
サーバオブジェクトを受信する子プロセス:
process.on('message', function(m, server) {
if (m === 'server') {
server.on('connection', function (socket) {
socket.end('handled by child');
});
}
});
サーバは親プロセスと子プロセスで共有されることに注意してください。 これはコネクションが時には親あるいは子で処理されることを意味します。
dgram
サーバのワークフローも同じです。
connection
イベントの代わりに message
イベントを監視し、
server.listen
の代わりに server.bind
を使用してください
(現時点では UNIX プラットフォームでのみサポートされています)。
Example: sending socket object#
これはソケットを送信する例です。
これは二つの子プロセスを起動し、コネクションのリモートアドレスが VIP
(74.125.127.100
) ならソケットを "special" 子プロセスに送信します。
その他のソケットは "normal" プロセスに送られます。
var normal = require('child_process').fork('child.js', ['normal']);
var special = require('child_process').fork('child.js', ['special']);
// Open up the server and send sockets to child
var server = require('net').createServer();
server.on('connection', function (socket) {
// if this is a VIP
if (socket.remoteAddress === '74.125.127.100') {
special.send('socket', socket);
return;
}
// just the usual dudes
normal.send('socket', socket);
});
server.listen(1337);
chold.js
は次のようになります:
process.on('message', function(m, socket) {
if (m === 'socket') {
socket.end('You were handled as a ' + process.argv[2] + ' person');
}
});
一度ソケットが子プロセスに送信されると、親プロセスはもうソケットがいつ
破棄されるか知ることができないことに注意してください。
この状態を示すために,.connections
プロパティは null
になります。
この状態では、.maxConnections
も使わないことを推奨します。
child.disconnect()#
親プロセスと子プロセス間の IPC コネクションをクローズし、
他の接続を持たない子プロセスが自然に終了することを可能にします。
このメソッドを呼び出すと、親プロセスと子プロセスの両方で .connected
は
false
に設定され、メッセージを送信することはできなくなります。
プロセスが受信するメッセージがなければ、おそらくはすぐに 'disconnect'
イベントが生成されます。
子プロセスでも process.disconnect()
を呼び出せることに注意してください。
child_process.spawn(command, [args], [options])#
command
{String} 実行するコマンドargs
{Array} 文字列による引数の配列options
{Object}cwd
{String} 子プロセスのカレントワーキングディレクトリstdio
{Array|String} 子プロセスの標準入出力の設定 (後述)。customFds
{Array} Deprecated 子プロセスが標準入出力として使用する ファイル記述子の配列 (後述)env
{Object} 環境変数として与えるキー・値のペアdetached
{Boolean} 子プロセスがプロセスグループのリーダになるかどうか (後述)。uid
{Number} このプロセスのユーザ識別子を設定します (setuid(2) を参照)。gid
{Number} このプロセスのグループ識別子を設定します (setgid(2) を参照)。
- return: {ChildProcess object}
args
をコマンドライン引数として、与えられた command
で新しいプロセスを起動します。
args
が省略された場合、空の配列がデフォルトとなります。
第 3 引数は追加のオプションを指定するために使われ、そのデフォルトは:
{ cwd: undefined,
env: process.env
}
cwd
で起動されたプロセスのワーキングディレクトリを指定することができます。
env
は新しいプロセスに見える環境変数を指定するために使います。
ls -lh /usr
を実行して stdout
、stderr
、および終了コードを取得する例:
var spawn = require('child_process').spawn,
ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
ls.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
ls.on('close', function (code) {
console.log('child process exited with code ' + code);
});
とても手の込んだ方法で実行する 'ps ax | grep ssh' の例:
var spawn = require('child_process').spawn,
ps = spawn('ps', ['ax']),
grep = spawn('grep', ['ssh']);
ps.stdout.on('data', function (data) {
grep.stdin.write(data);
});
ps.stderr.on('data', function (data) {
console.log('ps stderr: ' + data);
});
ps.on('close', function (code) {
if (code !== 0) {
console.log('ps process exited with code ' + code);
}
grep.stdin.end();
});
grep.stdout.on('data', function (data) {
console.log('' + data);
});
grep.stderr.on('data', function (data) {
console.log('grep stderr: ' + data);
});
grep.on('close', function (code) {
if (code !== 0) {
console.log('grep process exited with code ' + code);
}
});
exec の失敗をチェックする例:
var spawn = require('child_process').spawn,
child = spawn('bad_command');
child.stderr.setEncoding('utf8');
child.stderr.on('data', function (data) {
if (/^execvp\(\)/.test(data)) {
console.log('Failed to start child process.');
}
});
spawn()
は空の options
オブジェクトを受け取ると、
process.env
を使うのではなく,空の環境変数で子プロセスを起動します。
これは廃止された API との互換性のためです。
child_process.spawn()
の stdio
オプションは配列で、
それぞれのインデックスは子プロセスの fd に対応します。
要素の値は以下のいずれかです:
'pipe'
- 子プロセスと親プロセスの間でパイプを作成します。 パイプの親側の端点はchild_process
オブジェクトのプロパティChildProcess.stdio[fd]
として親プロセスに公開されます。 fd 0~2 はそれぞれ、ChildProcess.stdin
、ChildProcess.stdout
、ChildProcess.stderr
としても参照可能です。'ipc'
- 親プロセスと子プロセスの間でメッセージパッシングのための IPC チャネル/ファイル記述子を作成します。ChildProcess
は標準入出力に高々一つの IPC ファイル記述子を持ちます。 このオプションを設定すると、ChildProcess.send()
メソッドが有効になります。 子プロセスがこのファイル記述子に JSON メッセージを書き込むと、 それはChildProcess.on('message')
を引き起こします。 子プロセスが Node.js プログラムなら、IPC チャネルの存在はprocess.send()
およびprocess.on('message')
を有効にします。'ignore'
- 子プロセスにファイル記述子を設定しません。 Node は子プロセスを起動する際、常に fd 0~2 をオープンすることに 注意してください。これらのうちのどれかが'ignore'
の場合、node は/dev/null
をオープンして、それを子プロセスの fd に割り当てます。Stream
オブジェクト - tty、ファイル、ソケット、またはパイプを参照する 読み込みまたは書き込み可能なストリームを子プロセスと共有します。 ストリームの下層にあるファイル記述子は、子プロセスのstdio
配列の 対応する位置にコピーされます。 ストリームは下層のファイル記述を持っていなければならないことに 注意してください (ファイルストリームは'open'
イベントが発生するまで それを持ちません)。- 非負整数 - 整数の値を親プロセスが現在オープンしているファイル記述子として
解釈されます。
それは
Stream
オブジェクトの場合と同様に子プロセスに共有されます。 null
、undefined
- デフォルト値を使用します。stdio
のfd
が 0、1、または 2 (言い換えると stdin、stdout、または stderr) の場合はパイプが作成されます。fd が 3 以上の場合、デフォルトは'ignore'
です。
簡易な記法として、stdio
に配列ではなく以下の文字列の一つを指定することも
できます。
ignore
-['ignore', 'ignore', 'ignore']
pipe
-['pipe', 'pipe', 'pipe']
inherit
-[process.stdin, process.stdout, process.stderr]
または[0,1,2]
例:
var spawn = require('child_process').spawn;
// 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 present a
// startd-style interface.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });
detached
オプションが設定されると、子プロセスは新しいプロセスグループの
リーダになります。
これは親プロセスが終了しても子プロセスの実行が継続することを可能にします。
デフォルトでは、親プロセスは切り離された子プロセスの終了を待機します。
親プロセスが child
を待機することを防ぐには、child.unref()
メソッドを
使用し、親のイベントループに子のリファレンスカウントが含まれないようにします。
長時間実行する子プロセスを切り離し、出力をファイルにリダイレクトする例:
var fs = require('fs'),
spawn = require('child_process').spawn,
out = fs.openSync('./out.log', 'a'),
err = fs.openSync('./out.log', 'a');
var child = spawn('prg', [], {
detached: true,
stdio: [ 'ignore', out, err ]
});
child.unref();
長時間実行されるプロセスを開始するために detached
オプションを使用する場合、
その stdio
が親と接続するような構成を与えられない限り、そのプロセスは
バックグラウンドにとどまりません。
親の stdio
が継承されるなら、子プロセスは制御しているターミナルに
接続されたままです。
指定のファイル記述子を子プロセスの標準入出力に指定することを可能にする、
customFds
と呼ばれる廃止されたオプションがありました。
この API は全てのプラットフォームに移植可能ではないために削除されました。
customFds
は新しいプロセスの [stdin, stdout, stderr]
を既存のストリームに接続することを可能にしました;
-1
は新しいストリームが作られなければならないことを意味していました。
使用する場合は自己責任で。
関連項目: child_process.exec()
および child_process.fork()
child_process.exec(command, [options], callback)#
command
{String} 実行するコマンド、空白で区切られた引数を持ちますoptions
{Object}cwd
{String} 子プロセスのカレントワーキングディレクトリenv
{Object} 環境変数として与えるキー・値のペアencoding
{String} (Default: 'utf8')shell
{String} コマンドを実行するシェル (デフォルト: UNIX では'bin/sh'
、Windows では'cmd.exe'
。 シェルは UNIX では-c
スイッチを、 Windows では/s /c
を理解すべきです。 Windows では、コマンドラインの解析はcmd.exe
と互換であるべきです)。timeout
{Number} (Default: 0)maxBuffer
{Number} (Default: 200*1024)killSignal
{String} (Default: 'SIGTERM')
callback
{Function} プロセスが終了するとその出力を伴って呼び出されますerror
{Error}stdout
{Buffer}stderr
{Buffer}
- Return: ChildProcess object
コマンドをシェルで実行し、その出力をバッファに格納します。
var exec = require('child_process').exec,
child;
child = exec('cat *.js bad_file | wc -l',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
コールバックは引数 (error, stdout, stderr)
を得ます。
成功すると、error
は null
になります。
エラーだと、error
は Error
のインスタンスとなり、
err.code
は子プロセスの終了コード、
err.signal
はプロセスを終了させたシグナルとなります。
任意の第 2 引数でいくつかのオプションを指定することができます。 オプションのデフォルトは
{ encoding: 'utf8',
timeout: 0,
maxBuffer: 200*1024,
killSignal: 'SIGTERM',
cwd: null,
env: null }
もし timeout
が 0 より大きいと、
子プロセスは実行時間が timeout
ミリ秒よりも長くなると kill されます。
子プロセスは killSignal
で kill されます (デフォルト: 'SIGTERM'
)。
maxBuffer
は標準出力と標準エラーの最大のデータ量を指定します - この値を超えると子プロセスは kill されます。
child_process.execFile(file, [args], [options], [callback])#
file
{String} 実行するプログラムのファイル名args
{Array} 文字列による引数の配列options
{Object}cwd
{String} 子プロセスのカレントワーキングディレクトリenv
{Object} 環境変数として与えるキー・値のペアencoding
{String} (Default: 'utf8')timeout
{Number} (Default: 0)maxBuffer
{Number} (Default: 200*1024)killSignal
{String} (Default: 'SIGTERM')
callback
{Function} プロセスが終了するとその出力を伴って呼び出されますerror
{Error}stdout
{Buffer}stderr
{Buffer}
- Return: ChildProcess object
子シェルで実行する代わりに指定されたファイルを直接実行することを除いて
child_process.exec()
と同様です。
これは child_process.exec
より若干効率的で、同じオプションを持ちます。
child_process.fork(modulePath, [args], [options])#
modulePath
{String} 子プロセスで実行するモジュールargs
{Array} 文字列による引数の配列options
{Object}cwd
{String} 子プロセスのカレントワーキングディレクトリenv
{Object} 環境変数として与えるキー・値のペアencoding
{String} (デフォルト: 'utf8')execPath
{String} 子プロセスの作成に使われる実行ファイルexecArgv
{Array} 実行ファイルに渡される引数を表す文字列の配列 (デフォルトはprocess.execArgv
)。silent
{Boolean}true
の場合、子プロセスの標準入力、標準出力、 標準エラー出力は親プロセスにパイプされます。 そうでない場合は親プロセスから継承します。 より詳細はspawn()
のpipe
およびinherit
オプションを参照してください (デフォルトはfalse
)。
- Return: ChildProcess object
これは spawn()
の特別版で、Node プロセスを起動します。
返されるオブジェクトは通常の ChildProcess の全てのメソッドに加えて、
組み込みの通信チャネルを持ちます。
詳細は child.send(message, [sendHandle])
を参照してください。
これらの子 Node は、やはり V8 の新しいインスタンスです。 新しい Node ごとに少なくとも 30 ミリ秒の起動時間と 10MB のメモリを前提としてください。 つまり、数千の子プロセスを作ることは出来ません。
options
オブジェクト中の execPath
プロパティは、
現在の node
実行ファイルではない子プロセスの作成を可能にします。
デフォルトでは、子プロセスの環境変数 NODE_CHANNEL_FD
によって示される
ファイル記述子を通じて対話することに注意しなければなりません。
このファイル記述子における入力と出力は、改行で区切られた JSON オブジェクトです。