执行:显示标准输出“直播”
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了执行:显示标准输出“直播”相关的知识,希望对你有一定的参考价值。
我有这个简单的脚本:
var exec = require('child_process').exec;
exec('coffee -cw my_file.coffee', function(error, stdout, stderr) {
console.log(stdout);
});
我只是执行一个命令来编译一个咖啡脚本文件。但是stdout永远不会显示在控制台中,因为命令永远不会结束(因为咖啡的-w选项)。如果我直接从控制台执行命令,我得到这样的消息:
18:05:59 - compiled my_file.coffee
我的问题是:是否可以使用node.js exec显示这些消息?如果有,怎么样? !
谢谢
不要使用exec
。使用spawn
这是一个EventEmmiter
对象。然后你可以听到stdout
/ stderr
事件(spawn.stdout.on('data',callback..)
)发生的事情。
来自NodeJS文档:
var spawn = require('child_process').spawn,
ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', function (data) {
console.log('stdout: ' + data.toString());
});
ls.stderr.on('data', function (data) {
console.log('stderr: ' + data.toString());
});
ls.on('exit', function (code) {
console.log('child process exited with code ' + code.toString());
});
exec
缓冲输出,通常在命令执行完毕后返回它。
exec
还将返回一个EventEmitter的ChildProcess对象。
var exec = require('child_process').exec;
var coffeeProcess = exec('coffee -cw my_file.coffee');
coffeeProcess.stdout.on('data', function(data) {
console.log(data);
});
或者pipe
将子进程的stdout发送到主要的stdout。
coffeeProcess.stdout.pipe(process.stdout);
或者使用spawn继承stdio
spawn('coffee -cw my_file.coffee', { stdio: 'inherit' });
已经有几个答案,但是他们都没有提到最好(也是最简单)的方法,即使用spawn
和{ stdio: 'inherit' }
option。它似乎产生最准确的输出,例如当从git clone
显示进度信息时。
只需这样做:
var spawn = require('child_process').spawn;
spawn('coffee', ['-cw', 'my_file.coffee'], { stdio: 'inherit' });
感谢@MorganTouvereyQuilling在this comment指出这一点。
我想补充说,使用console.log()
从生成的进程输出缓冲区字符串的一个小问题是它添加了换行符,这可以将生成的进程输出扩展到其他行。如果用stdout
而不是stderr
输出process.stdout.write()
或console.log()
,那么你将从生成的进程'按原样'获得控制台输出。
我在这里看到了解决方案:Node.js: printing to console without a trailing newline?
希望能帮助某人使用上面的解决方案(这对于实时输出来说非常棒,即使它来自文档)。
受Nathanael Smith的回答和Eric Freese的评论启发,它可能很简单:
var exec = require('child_process').exec;
exec('coffee -cw my_file.coffee').stdout.pipe(process.stdout);
我发现将自定义exec脚本添加到执行此操作的实用程序中会很有帮助。
utilities.js
const { exec } = require('child_process')
module.exports.exec = (command) => {
const process = exec(command)
process.stdout.on('data', (data) => {
console.log('stdout: ' + data.toString())
})
process.stderr.on('data', (data) => {
console.log('stderr: ' + data.toString())
})
process.on('exit', (code) => {
console.log('child process exited with code ' + code.toString())
})
}
app.js
const { exec } = require('./utilities.js')
exec('coffee -cw my_file.coffee')
在审查了所有其他答案后,我最终得到了这个:
function oldSchoolMakeBuild(cb) {
var makeProcess = exec('make -C ./oldSchoolMakeBuild',
function (error, stdout, stderr) {
stderr && console.error(stderr);
cb(error);
});
makeProcess.stdout.on('data', function(data) {
process.stdout.write('oldSchoolMakeBuild: '+ data);
});
}
有时data
将是多行,因此oldSchoolMakeBuild
标题将出现一次多行。但这并不足以让我改变它。
child_process.spawn返回带有stdout和stderr流的对象。您可以点击stdout流来读取子进程发送回Node的数据。作为流的stdout具有“数据”,“结束”以及流具有的其他事件。当您希望子进程将大量数据返回到节点 - 图像处理,读取二进制数据等时,最好使用spawn。
所以你可以使用下面使用的child_process.spawn解决你的问题。
var spawn = require('child_process').spawn,
ls = spawn('coffee -cw my_file.coffee');
ls.stdout.on('data', function (data) {
console.log('stdout: ' + data.toString());
});
ls.stderr.on('data', function (data) {
console.log('stderr: ' + data.toString());
});
ls.on('exit', function (code) {
console.log('code ' + code.toString());
});
以上是关于执行:显示标准输出“直播”的主要内容,如果未能解决你的问题,请参考以下文章
Sphinx、reStructuredText 显示/隐藏代码片段
Golang PrintfSprintf Fprintf 格式化