command の 標準入出力 覚書
child_process.spawn(command [, args] [, options])
command
を 新規のプロセスで実行し、subprocess
を生成する。
(command
は 子プロセスとなる)
options.stdio
command の標準入出力先を設定する。
pipe
: デフォルト。commandの標準入出力は、subprocess.stdio とつながるinherit
: commandの標準入出力は、process.stdio が引き継がれるignore
:/dev/null
<Stream>
: ファイルへのリダイレクト
pipe
command
の 入出力が、 subprocess.stdio とつながる。
ps ax | grep ssh
の実現コード
const { spawn } = require('child_process'); // ps が subprocess const ps = spawn('ps', ['ax']); // grep が subprocess const grep = spawn('grep', ['ssh']); // subprocess.stdout を使って command の標準出力結果を受け取る ps.stdout.on('data', (data) => { grep.stdin.write(data); }); // subprocess.stdout を使って command の標準エラー結果を受け取る ps.stderr.on('data', (data) => { console.error(`ps stderr: ${data}`); }); // command の exit は subprocess を 使ってハンドリングできる 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()); });
サブプロセスがNode.jsツールの場合
process.stdio
が subprocess.stdio
につながる
親プロセス (pipe.js)
const { spawn } = require('child_process') // subprocessの生成 const subprocess = spawn('./subcommand.js', ['hello']) subprocess.stdout.on('data', (data) => { console.log('subcommand answered: ') console.log(data.toString('utf-8')) })
子プロセス (subcommand.js)
#!/usr/bin/env node const args = process.argv.slice(2) // 親のsubprocess.stdoutに書き込まれる process.stdout.write(`You inputed: ${args}\n`) process.stdout.end('over')
実行
$ node pipe.js subcommand answered: You inputed: hello over
inherit
command
の入出力が process.stdio (標準入出力(0, 1, 2)) とそのままつながる。
subprocess.stdout
, subprocess.stderr
へのアクセスはクラッシュする。
vimの起動。(vimの標準入出力にsubprocess.stdioを割り当てるとvimが起動できない)
const { spawn } = require('child_process'); const subprocess = spawn( 'sh', [ '-c', 'vim' ], { stdio: ['inherit', 'inherit', 'inherit'] } );
sh -c
: 最初の引数を command として実行する
覚書
登場人物
- 自身のスクリプト = 親プロセス
command
= 子プロセスsubprocess
= child_process.spawn(command[, args][, options]) メソッドで生成されるインスタンス。 commandとのやり取りに使う。
プロセスのdetachも可能
options.detached
を trueにすることで、親プロセスから独立して子プロセスを実行する。
プロセス通信も可能
IPCチャンネルを通してcommand
とのプロセス通信が可能。
(subprocessを通して行う。エレガントやんか。)
参照
class ChildProcess
subprocessは、ChildProcessのサブクラスのインスタンス?