节点child_process.spawn多个命令

Дан*_*мов 15 keytool spawn node.js

我想自动创建和提取密钥库.我面临的问题是如何使用' |来加入命令 '符号或类似的解决方案.

//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'));
      })
Run Code Online (Sandbox Code Playgroud)

Jan*_*ůna 30

从Node.js v6中,您可以shellspawn方法中指定一个选项,该选项将使用shell运行命令,因此可以使用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);
});
Run Code Online (Sandbox Code Playgroud)

将在node.js版本小于6时触发错误:

Error: spawn ls && ls && ls ENOENT
Run Code Online (Sandbox Code Playgroud)

但是在版本6及更高版本上它将返回预期结果:

node app.js
STDOUT: app.js

STDOUT: app.js
app.js

Child exited with code: 0
Run Code Online (Sandbox Code Playgroud)


Che*_*hev 9

|,因为它像数据的管道流一起在命令行上的符号被称为"管道".你想要的是获得你正在执行的命令的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);
Run Code Online (Sandbox Code Playgroud)

上面的例子产生了"echo"和"grep"命令.它将echo进程stdout流中的任何输出传递给grep进程的stdin流.最后,我们将grep流程的stdout流传输到父流程(您的节点流程)stdin流,以便您可以在终端中查看输出.

输出将是"快速棕色狐狸",因为我在中间放置了换行符,而grep只匹配包含"brown"的第一行.

您可以使用该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);
});
Run Code Online (Sandbox Code Playgroud)

或者不是传递回调函数,你可以只输出输出,process.stdin如果你关心的只是看到命令输出.

exec(cmdString).stdout.pipe(process.stdin);
Run Code Online (Sandbox Code Playgroud)

这是我认为您的代码应该使用的简单示例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.'));
});
Run Code Online (Sandbox Code Playgroud)

或使用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.'));
});
Run Code Online (Sandbox Code Playgroud)