如何监视ssh文件传输和输出到日志文件的进度

eaj*_*eaj 5 unix bash scripting

我正在编写一个bash脚本来定期将数据传输到远程系统.我有一个生成流的本地命令,以及一个使用它的远程命令,所以我做的是这样的:

generate_data | ssh remoteserver.example.com consume_data
Run Code Online (Sandbox Code Playgroud)

(我设置了ssh键,所以我可以非交互式地执行此操作.)这很好用.但是,由于这将是一个自动化过程(作为一个cron作业运行),有时可能会在有限的带宽上传输大量数据,我希望能够在我的日志文件中定期进行更新.我曾经想过使用pv(管道查看器),这是我能想到的最好的:

generate_data | pv -fb | ssh remoteserver.example.com consume_data
Run Code Online (Sandbox Code Playgroud)

再次,它的工作原理...... 但是 pv真的是用终端输出编写的,所以我最终在日志中看起来很乱

2.06MB^M2.19MB^M2.37MB^M 2.5MB^M2.62MB^M2.87MB^M3MB^M3.12MB^M3.37MB
Run Code Online (Sandbox Code Playgroud)

我更喜欢日志消息

<timestamp> 2.04MB transferred...
<timestamp> 3.08MB transferred...
Run Code Online (Sandbox Code Playgroud)

如果有人对如何做到这一点有任何聪明的想法,或者通过不同的论点pv或通过其他机制,我将不胜感激.

编辑:感谢您的答案到目前为止.当然,有很多可能的家庭酿造解决方案; 我希望找到一些可以"开箱即用"的东西.(并不是说我排除了自酿;最终可能是最简单的事情.既然pv已经完成了我所需要的98%,我宁愿不重新发明它.)

PostScript:这是我最终使用的那条线,希望它可能在某些时候帮助别人.

{ generate_data | pv -fbt -i 60 2>&3 | ssh remoteserver consume_data } 3>&1 | awk -vRS='\r' '{print $1 " transferred in " $2; fflush();}' >> logfile
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 5

如果你想坚持下去pv,你可以稍微后处理它的输出.至少将CR转换为LF.

{ generate_data | pv -bft 2>&3 | consume_data >/dev/null; } 3>&1 | tr '\015' '\012'
Run Code Online (Sandbox Code Playgroud)

使用awk进行更高级的处理.

{ generate_data | pv -bft 2>&3 | consume_data >/dev/null; } 3>&1 |
awk -vRS='\r' '{print $2, $1 " transferred"}'
Run Code Online (Sandbox Code Playgroud)

但请记住,标准文本处理实用程序只有在打印到终端时才会在每行末尾刷新输出.因此,如果您管道pv输出到管道或文件的其他实用程序,由于缓冲将导致不可忽略的延迟.如果您有GNU awk或其他具有该fflush功能的实现(它是常见的但不是标准的),请使其在每行上刷新其输出:

{ generate_data | pv -bft 2>&3 | consume_data >/dev/null; } 3>&1 |
awk -vRS='\r' '{print $2, $1 " transferred"; fflush()}'
Run Code Online (Sandbox Code Playgroud)