我正在编写一个相对简单的应用程序,允许内部系统通过REST调用请求从远程服务器到另一个远程服务器的复制过程(使用rsync)。
我已经熟悉了express框架,并开始尝试使用child_process库,但遇到了一个小问题。
我成功地使用node的childProcess.spawn()启动了rsync进程,但我的问题是,rsync将其进度行输出为带有回车符(\r)而不是换行符(\n)的缓冲区。因此STDOUT事件(process.stdout.on('data', {}))仅在设置传输之前和复制完成后被调用一次,因为在回车符上不会刷新STDOUT数据,只有在作业完成时才会有进度更新和换行符。
最新版本的rsync(3.1.0)中有一个开关,可以将输出缓冲区结尾改为\n而不是\r,但很遗憾,我所在的公司将不会在很长一段时间内采用这个版本。
我按照通常的方式生成和读取child_process...
所以你可以看到,当rsync输出新的一行(出现“OUT:”时)才会调用stdout.on('data')。
我的问题是,我能改变这个吗?也许将流通过转换使其在出现\r时刷新?然后我可以使用正则表达式对该行进行匹配并再次提供进度更新。
如果失败,我想我的另一个选择就是生成另一个进程来监视不断增长的文件?
非常感谢任何帮助/建议。
我已经熟悉了express框架,并开始尝试使用child_process库,但遇到了一个小问题。
我成功地使用node的childProcess.spawn()启动了rsync进程,但我的问题是,rsync将其进度行输出为带有回车符(\r)而不是换行符(\n)的缓冲区。因此STDOUT事件(process.stdout.on('data', {}))仅在设置传输之前和复制完成后被调用一次,因为在回车符上不会刷新STDOUT数据,只有在作业完成时才会有进度更新和换行符。
最新版本的rsync(3.1.0)中有一个开关,可以将输出缓冲区结尾改为\n而不是\r,但很遗憾,我所在的公司将不会在很长一段时间内采用这个版本。
我按照通常的方式生成和读取child_process...
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);
}
});
}
......控制台输出.......
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输出新的一行(出现“OUT:”时)才会调用stdout.on('data')。
我的问题是,我能改变这个吗?也许将流通过转换使其在出现\r时刷新?然后我可以使用正则表达式对该行进行匹配并再次提供进度更新。
如果失败,我想我的另一个选择就是生成另一个进程来监视不断增长的文件?
非常感谢任何帮助/建议。