私は現在、Ruby から Node.js に CLI ライブラリを移植中です。私のコードでは、必要に応じていくつかのサードパーティ バイナリを実行します。Node でこれをどのように実現するのが最適かはわかりません。
以下は、PrinceXML を呼び出してファイルを PDF に変換する Ruby の例です。
cmd = system("prince -v builds/pdf/book.html -o builds/pdf/book.pdf")
Node での同等のコードは何ですか?
ベストアンサー1
さらに新しいバージョンの Node.js (v8.1.4) では、イベントと呼び出しは古いバージョンと類似または同一ですが、標準の新しい言語機能を使用することをお勧めします。例:
バッファリングされた非ストリーム形式の出力(一度にすべて取得)の場合は、child_process.exec
:
const { exec } = require('child_process');
exec('cat *.js bad_file | wc -l', (err, stdout, stderr) => {
if (err) {
// node couldn't execute the command
return;
}
// the *entire* stdout and stderr (buffered)
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
Promise と一緒に使用することもできます:
const util = require('util');
const exec = util.promisify(require('child_process').exec);
async function ls() {
const { stdout, stderr } = await exec('ls');
console.log('stdout:', stdout);
console.log('stderr:', stderr);
}
ls();
データをチャンクで段階的に受信したい場合(ストリームとして出力)、child_process.spawn
:
const { spawn } = require('child_process');
const child = spawn('ls', ['-lh', '/usr']);
// use child.stdout.setEncoding('utf8'); if you want text chunks
child.stdout.on('data', (chunk) => {
// data from standard output is here as buffers
});
// since these are streams, you can pipe them elsewhere
child.stderr.pipe(dest);
child.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
これらの関数には同期版があります。child_process.execSync
:
const { execSync } = require('child_process');
// stderr is sent to stderr of parent process
// you can set options.stdio if you want it to go elsewhere
let stdout = execSync('ls');
const { spawnSync} = require('child_process');
const child = spawnSync('ls', ['-lh', '/usr']);
console.log('error', child.error);
console.log('stdout ', child.stdout);
console.log('stderr ', child.stderr);
注:次のコードはまだ機能しますが、主に ES5 以前のユーザーを対象としています。
Node.jsで子プロセスを生成するモジュールについては、ドキュメンテーション(v5.0.0) コマンドを実行し、その完全な出力をバッファとして取得するには、child_process.exec
:
var exec = require('child_process').exec;
var cmd = 'prince -v builds/pdf/book.html -o builds/pdf/book.pdf';
exec(cmd, function(error, stdout, stderr) {
// command output is in stdout
});
大量の出力が予想される場合など、ストリームでプロセスI/Oを処理する必要がある場合は、child_process.spawn
:
var spawn = require('child_process').spawn;
var child = spawn('prince', [
'-v', 'builds/pdf/book.html',
'-o', 'builds/pdf/book.pdf'
]);
child.stdout.on('data', function(chunk) {
// output will be here in chunks
});
// or if you want to send output elsewhere
child.stdout.pipe(dest);
コマンドではなくファイルを実行する場合は、次のようにするとよいかもしれません。child_process.execFile
は、 とほぼ同じパラメータですspawn
が、出力バッファを取得するための のような 4 番目のコールバック パラメータがありますexec
。これは次のようになります。
var execFile = require('child_process').execFile;
execFile(file, args, options, function(error, stdout, stderr) {
// command output is in stdout
});
現在v0.11.12Nodeは同期spawn
とをサポートするようになりましexec
た。上記のメソッドはすべて非同期であり、同期の対応メソッドがあります。それらのドキュメントはここスクリプトには便利ですが、子プロセスを非同期に生成するために使用されるメソッドとは異なり、同期メソッドはインスタンスを返さないことに注意してください。ChildProcess
。