我同步生成一些命令并想要两件事:
我写了这段代码:
var spawnSync = require('child_process').spawnSync;
var result = spawnSync('ls', [ '-l', '-a' ]);
var savedOutput = result.stdout;
console.log(String(savedOutput));
所以,我将stdout存储在savedOutput变量中 - 没关系,然后将其记录下来。但是我还没把它管到stdout。如果生成的进程很长并逐个写字符串,我会看到空屏很长时间,最后我看到整个进程的stdout。
我添加了滚动选项:
var spawnSync = require('child_process').spawnSync;
var result = spawnSync('ls', [ '-l', '-a' ], {
stdio: [ 'ignore', 1, 2 ]
});
var savedOutput = result.stdout;
console.log(String(savedOutput));
生成过程的标准输出通过管道输送到标准输出 - 没关系。但是result.stdout是空的。
我试过使用流:
var spawnSync = require('child_process').spawnSync;
var stream = require('stream');
var grabber = new stream.Writable();
grabber._write = function(chunk, enc, done) {
console.log('Chunk:');
console.log(String(chunk));
done();
};
var result = spawnSync('ls', [ '-l', '-a' ], {
stdio: [ 'ignore', grabber, 2 ]
});
...但收到错误:
internal/child_process.js:795
throw new TypeError('Incorrect value for stdio stream: ' +
^
TypeError: Incorrect value for stdio stream: Writable
如果我设置grabber.fd = 2
,我不会收到错误,但是子标准输出管道输入stdout而不是抓取器。
因此。如何将子stdout保存到变量中并同时将其传递给stdout?
答案 0 :(得分:2)
我认为问题在于“ spawnSync”是同步的,并且直到子进程退出后才将控制权返回给节点。这意味着节点在执行子代期间不进行任何处理,因此看不到子代的任何中间输出。
您需要使用非“同步”生成。这将带来更多的复杂性,因为您的代码是异步的,并且您需要等待“关闭”事件以确保收集了子数据。您需要弄清楚如何使用stderr。像这样:
const spawn = require('child_process').spawn;
const lsChild = spawn('ls', [ '-l', '-a' ]);
let savedOutput = '';
lsChild.stdout.on('data', data => {
const strData = data.toString();
console.log(strData);
savedOutput += strData;
});
lsChild.stderr.on('data', data => {
assert(false, 'Not sure what you want with stderr');
});
lsChild.on('close', code => {
console.log('Child exited with', code, 'and stdout has been saved');
// at this point 'savedOutput' contains all your data.
});
答案 1 :(得分:2)
有两种可能的解决方案,都涉及spawnSync
的{{1}}。
https://repl.it/repls/MundaneConcernedMetric
有此代码的实时版本。options
除了const spawnSync = require('child_process').spawnSync;
// WITH NO OPTIONS:
// stdout is here, but is encoded as 'buffer'
const result_noOptions = spawnSync('ls', [ '-l', '-a' ]); // won't print anything
console.log(result_noOptions.stdout); // will print <Buffer ...> on completion
// WITH { encoding: 'utf-8'} OPTIONS:
// stdout is also here, _but only printed on completion of spawnSync_
const result_encoded = spawnSync('ls', [ '-l', '-a' ], { encoding: 'utf-8' }); // won't print anything
console.log(result_encoded.stdout); // will print ls results only on completion
// WITH { stdio: 'inherit' } OPTIONS:
// there's no stdout, _because it prints immediately to your terminal_
const result_inherited = spawnSync('ls', [ '-l', '-a' ], { stdio: 'inherit'}); // will print as it's processing
console.log(result_inherited.stdout); // will print null
,您还可以获得:stdout
,pid
,output
,stdout
,stderr
,{{1 }}和status
。
https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options
答案 2 :(得分:0)
这会解决您的问题吗?
var spawnSync = require('child_process').spawnSync;
var result = spawnSync('ls', [ '-l', '-a' ], {
cwd: process.cwd(),
env: process.env,
stdio: 'pipe',
encoding: 'utf-8'
});
var savedOutput = result.stdout;
console.log(String(savedOutput));
答案 3 :(得分:-2)
stdout
没有帮助获取spawnSync的输出,因此使用它来代替在变量中存储output
。我正在使用Windows cmd
var cp = require('child_process');
var ls = cp.spawnSync('cmd.exe', ['/c', 'my.bat']);
var output = result.output.toString();