Child_process处理带有回车符(\r)的STDOUT流 [英] Child_process handling a STDOUT stream with carriage return (\r)
问题描述
我正在编写一个简单的应用程序,它允许工作中的内部系统请求从远程服务器到使用REST调用促成的另一台远程服务器的复制过程(使用rsync)。
I'm writing a simple(ish) application that allows an internal system at work to request a copy process (using rsync) from a remote server to another remote server instigated using a REST call.
我已经对Express框架非常熟悉,并且刚刚开始尝试child_process库,偶然发现了一个小问题。
I'm already familiar enough with the express framework, and have just started experimenting with the child_process library, and stumbled upon a small problem.
我使用节点的 childProcess.spawn()
成功启动了rsync进程,我的问题是rsync输出的进度行缓冲有回车符(\r),而不是换行符(\n)。结果,STDOUT事件 process.stdout.on('data',{})
在设置传输之前仅调用一次,然后在复制之后已经完成,因为在作业完成时,STDOUT数据不会在回车时刷新,而随着进度的更新,只有换行符。
I am successfully starting rsync processes using node's childProcess.spawn()
, my issue is that rsync outputs its progress line-buffered with a carriage return (\r) instead of an newline (\n). As a result the STDOUT event, process.stdout.on('data', {})
is only called once before saying it's setting up the transfer, and then after the copy has finished, as STDOUT data isn't flushed on a carriage return, as the progress updates, only a newline, when the job finishes.
最新版本的rsync(3.1.0)将输出缓冲区的结尾更改为\n而不是\r,但是不幸的是,我工作的公司很长时间都不会采用此版本。
There is a switch in the latest version of rsync (3.1.0) to change the output buffer endings to \n instead of \r but unfortunately, the company I work at will not be adopting this version for a long time.
我以通常的方式生成并读取child_process...。
I'm spawning and reading the child_process in the usual way....
var doCopy = function (onFinish) {
var process = childProcess.spawn('ssh', [
source.user + "@" + source.host,
"rsync",
"-avz",
"--progress",
source.path + source.file,
"-e ssh",
dest.user + "@" + dest.host + ":" + dest.path
]);
process.on('error', function (error) {
console.log("ERR: " + error.code);
})
process.stdout.on('data', function (data) {
console.log("OUT: " + data);
});
process.stderr.on('data', function (data) {
console.log("ERR: " + data);
});
process.on('close', function (code) {
console.log("FIN: " + code);
if(onFinish){
onFinish(code);
}
});
}
..控制台输出为....
..and the console output is....
OUT: building file list ...
OUT:
1 file to consider
OUT: test4.mp4
32,768 0% 0.00kB/s 0:00:00
169,738,240 32% 161.84MB/s 0:00:02
338,165,760 64% 161.32MB/s 0:00:01
504,692,736 96% 160.53MB/s 0:00:00
524,288,000 100% 160.35MB/s 0:00:03 (xfr#1, to-chk=0/1)
OUT:
sent 509,959 bytes received 46 bytes 113,334.44 bytes/sec
total size is 524,288,000 speedup is 1,028.01
FIN: 0
因此您可以看到,仅当rsync输出新行时才调用stdout.on('data,)
So you can see that the stdout.on('data,) is only called when rsync outputs a new line (where there is an 'OUT:').
我的问题是,我可以更改吗?也许在发生\r时将流通过转换进行冲洗?然后我可以对该行进行正则表达式并再次提供进度更新。
My question is, can I change this? Maybe put the stream through a transform to flush when a \r occurs? Then I can regex the line and offer a progress update back again.
如果失败了,我想我唯一的选择就是生成另一个进程来监视正在增长的文件?
Failing this, I suppose my only other option would be to spawn another process to monitor the growing file?
非常感谢任何帮助/建议。
Any help/advise is very much appreciated.
推荐答案
I已经找到此非常好的模块,它确实可以实现我想要实现的目标。让我可以用任何字符(在本例中为 \r)分隔标准输出缓冲区,并触发新的标准输出事件来处理数据。就像...。
I've found this very good module that does exactly what I was trying to achieve. Allows me to delimit the stdout buffer by any character (in my case '\r') and trigger a new stdout event to handle the data. Like....
var splitter = process.stdout.pipe(StreamSplitter("\r"));
splitter.on('token', function (data) {
console.log("OUT: " + data);
});
splitter.on('done', function (data) {
console.log("DONE: " + data);
});
这篇关于Child_process处理带有回车符(\r)的STDOUT流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!