web-dev-qa-db-fra.com

Node child_process.spawn plusieurs commandes

Je veux automatiser la création et l'extraction de keystore. Le problème auquel je suis confronté est de savoir comment joindre les commandes en utilisant le symbole '' ou une solution similaire.

//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'));
      })
21

À partir de Node.js v6, vous pouvez spécifier une option Shell dans la méthode spawn qui exécutera la commande à l'aide de Shell et il est donc possible de chaîne de commandes utilisant la méthode spawn.

Par exemple ceci:

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

Va déclencher une erreur sur la version node.js inférieure à 6:

Error: spawn ls && ls && ls ENOENT

Mais sur la version 6 et supérieure, il retournera le résultat attendu:

node app.js
STDOUT: app.js

STDOUT: app.js
app.js

Child exited with code: 0
35
Jan Jůna

Le symbole | Sur la ligne de commande est appelé "canalisation" car il ressemble à la canalisation de flux de données ensemble. Ce que vous voulez, c'est obtenir les flux stdin (entrée standard) et stdout (sortie standard) pour les commandes que vous exécutez.

Par exemple, voici comment vous pouvez générer la commande echo et diriger sa sortie vers 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);

L'exemple ci-dessus génère à la fois les commandes "echo" et "grep". Il dirige n'importe quelle sortie du flux echo du processus stdout vers le flux grep du processus stdin. Enfin, nous dirigeons le flux grep du processus stdout vers le flux parent du processus (votre processus de noeud) stdin afin que vous puissiez voir la sortie dans votre terminal.

La sortie serait "Le renard brun rapide" car j'ai mis un caractère de nouvelle ligne au milieu et le grep ne correspondait qu'à la première ligne contenant "brun".

Vous pouvez utiliser la fonction exec pour obtenir le même résultat. Cela pourrait être plus difficile à maintenir à l'avenir, mais si tout ce dont vous avez besoin est d'exécuter rapidement un ensemble de commandes canalisées, vous pouvez entrer la chaîne de ligne de commande complète (y compris les symboles de canalisation) et la transmettre à 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);
});

Ou au lieu de passer la fonction de rappel, vous pouvez simplement diriger la sortie vers process.stdin Si tout ce qui vous intéresse est de voir la sortie de la commande.

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

Voici un exemple rapide de ce que je pense que votre code devrait ressembler en utilisant spawn. Peut nécessiter des ajustements car cela semble spécifique à ce que vous faites.

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

Ou en utilisant 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