web-dev-qa-db-ja.com

Node child_process.spawn複数のコマンド

キーストアの作成と抽出を自動化したいと思います。私が直面している問題は、 ''記号または同様のソリューションを使用してコマンドを結合する方法です。

//Original Command    
var command='keytool -exportcert -storepass mypass -keypass mypass  
-alias myalias -keystore mykey.keystore | openssl sha1 -binary | openssl base64';

//Arguments for the spawn    
var keyArgs = [
      '-exportcert',
      '-storepass','mypass',
      '-keypass','mypass',
      '-alias','myalias',
      '-keystore',"myjey.keystore",


      'openssl','sha1',
      '-binary',
      'openssl','base64',


  ];
exec('keytool',keyArgs,{cwd:appCreateFolder+"/"+opt.id+"/Certificates"},function(e){
    console.log(chalk.cyan('Key created'));
      })

Node.js v6から、Shellメソッドでspawnオプションを指定して、シェルを使用してコマンドを実行することができるため、spawnメソッドを使用してコマンドをチェーンするが可能です。

例えばこれは:

var spawn = require('child_process').spawn;
var child = spawn('ls && ls && ls', {
  Shell: true
});
child.stderr.on('data', function (data) {
  console.error("STDERR:", data.toString());
});
child.stdout.on('data', function (data) {
  console.log("STDOUT:", data.toString());
});
child.on('exit', function (exitCode) {
  console.log("Child exited with code: " + exitCode);
});

Node.jsバージョン6未満でエラーがトリガーされます:

Error: spawn ls && ls && ls ENOENT

しかし、バージョン6以降では、期待される結果が返されます。

node app.js
STDOUT: app.js

STDOUT: app.js
app.js

Child exited with code: 0
35
Jan Jůna

コマンドラインの|記号は、データのストリームを一緒にパイプするようなものなので、「パイピング」と呼ばれます。必要なのは、実行しているコマンドのstdin(標準入力)およびstdout(標準出力)ストリームを取得することです。

たとえば、次のようにしてechoコマンドを生成し、出力をgrepにパイプします。

var spawn = require('child_process').spawn;
var echo = spawn('echo', ['The quick brown fox\njumped over the lazy dog.']);
var grep = spawn('grep', ['brown']);

echo.stdout.pipe(grep.stdin);
grep.stdout.pipe(process.stdin);

上記の例では、「echo」コマンドと「grep」コマンドの両方が生成されます。 echoプロセスのstdoutストリームからの出力をgrepプロセスのstdinストリームにパイプします。最後に、grepプロセスのstdoutストリームを親プロセス(ノードプロセス)のstdinストリームにパイプして、ターミナルで出力を確認できるようにします。

中央に改行文字を入れ、grepが「brown」を含む最初の行のみに一致したため、出力は「The quick brown fox」になります。

exec関数を使用して同じ結果を得ることができます。将来的には維持が難しくなる可能性がありますが、パイプ処理されたコマンドのセットをすばやく実行する必要がある場合は、コマンドライン文字列全体(パイプ記号を含む)を入力してexecに渡すことができます。

var exec = require('child_process').exec;
var cmdString = 'grep "The quick brown fox\njumped over the lazy dog." | grep "brown"';
exec(cmdString, (err, stdout, stderr) => {
  console.log(stdout);
});

または、コールバック関数を渡す代わりに、出力をprocess.stdinにパイプするだけで、コマンド出力を確認するだけで済みます。

exec(cmdString).stdout.pipe(process.stdin);

これは、コードがspawnを使用してどのように見えるかを簡単に示す例です。それはあなたがやっていることに固有のように見えるので、微調整が必​​要な場合があります。

var keyArgs = [
  '-exportcert',
  '-storepass','mypass',
  '-keypass','mypass',
  '-alias','myalias',
  '-keystore',"myjey.keystore",
  'openssl','sha1',
  '-binary',
  'openssl','base64',
];
var keyOpts = {
  cwd: `${appCreateFolder}/${opt.id}/Certificates`
};

var spawn = require('child_process').spawn;
var keytool = spawn('keytool', keyArgs, keyOpts);
var opensslBinary = spawn('openssl', ['sha1', '-binary']);
var opensslBase64 = spawn('openssl', ['base64']);

keytool.stdout.pipe(opensslBinary.stdin);
opensslBinary.stdout.pipe(opensslBase64.stdin);
opensslBase64.stdout.pipe(process.stdin);

opensslBase64.on('close', () => {
  console.log(chalk.cyan('Key created.'));
});

またはexecを使用:

var exec = require('child_process').exec;
var cmdString = 'keytool -exportcert -storepass mypass -keypass mypass -alias myalias -keystore mykey.keystore | openssl sha1 -binary | openssl base64';
var cmdOpts = {
  cwd: `${appCreateFolder}/${opt.id}/Certificates`
};
exec(cmdString, cmdOpts, () => {
  console.log(chalk.cyan('Key created.'));
});
14
Chev