美文网首页
命令行输出保存到文件时,如何清理命令行反复输出的进度信息给文件瘦

命令行输出保存到文件时,如何清理命令行反复输出的进度信息给文件瘦

作者: xun66 | 来源:发表于2023-06-20 01:58 被阅读0次

本文属记录性的文章,仅供参考

问题描述

写shell脚本时,如果将输出保存到文件,有些支持在屏幕上动态显示进度的命令(如docker pullcurlwgetaws s3ossutil等)会通过回车符CR,即 \r来更新最后一行已经输出过的内容,用来更新进度百分比、进度条等。
比如阿里云的ossutil工具,在交互式终端使用时,它的进度条会不断更新:

# 过程中
root@localhost:~$ ossutil cp  oss://oss-bucket/software/example-desktop-11.0.0-win64-zip-chs.zip .
Total num: 1, size:  2,315,088,831. Dealed num: 0, OK size: 1,070,261,950, Progress: 51.001%, Speed: 107325.88KB

# 完成后
root@localhost:~$ ossutil cp  oss://oss-bucket/software/example-desktop-11.0.0-win64-zip-chs.zip .
Succeed: Total num: 1, size: 2,315,088,831. OK num: 1(download 1 objects).                                        

average speed 136382000(byte/s)

19.781217(s) elapsed

完成后的总结报告,共有约169个字符。

但若将这些命令的输出(stdout、stderr)重定向到文件时,输出的这些中间过程便也会进入文件,形成超长的一段内容(这里测试时是702字符),如下:

# 将标准输出重定向到文件
root@localhost:~$ ossutil cp  oss://oss-bucket/software/example-desktop-11.0.0-win64-zip-chs.zip . > down.log
root@localhost:~$ ls -l down.log
-rw-r--r-- 1 root root 702 Jun 21 01:19 down.log # 足足有702字符长

root@localhost:~$ less down.log #查看文件内容
^MTotal num: 1, size: 2,088,315,831. Dealed num: 0, OK size: 1,049,378,790, Progress: 50.250%, Speed: 203556.46KB/s^M 
^MTotal num: 1, size: 2,088,315,831. Dealed num: 0, OK size: 1,388,730,140, Progress: 66.500%, Speed: 62521.22KB/s^M
^MTotal num: 1, size: 2,088,315,831. Dealed num: 0, OK size: 1,931,692,300, Progress: 92.500%, Speed: 105637.46KB/s^M  
^MSucceed: Total num: 1, size: 2,088,315,831. OK num: 1(download 1 objects).

average speed 124630000(byte/s)

16.756609(s) elapsed
down.log (END)

这些^M实际上就是\r,将此行光标覆写。如果命令执行的时间比较长,文件中将有非常多的这种进度信息。怎么让这类中间过程不进入最终的日志文件,只保留最终的文本,就像在终端上最后留下的信息一样?

方案一:由程序自动处理

很多命令会自行检测自己的标准输出是否为终端( isatty(3) ),若不是终端(如文件),程序的行为会自行改变,如禁用颜色高亮、自动静默进度输出等。若程序没有检测,或相应行为达不到要求,看下一个方案。

方案二:使用程序的命令行参数

不少命令(grep,curl,wget等),拥有一些控制输出方式的参数。通过使用命令-h--helpman 命令等方式,看看有没有关于quiet(-q),verbose(-v),silent(-s),no-progress相关的参数。

  • grep命令,使用--color=auto/always/never这样的命令强制控制颜色
  • curl命令,使用-s参数禁用stderr进度条输出
  • wget命令,使用-q参数禁用进度输出

但也有可能,你使用的命令并没有这样的参数(比如ossutil我没有找到),则继续往后看

方案三:直接关闭标准输出(简单粗暴)

直接 ossutil ... > /dev/null 问题解决

方案四:小工具col登场

我们可以了解一下col这个自带的命令(重点关注-b参数,文档页链接 col(1), col )

col过滤掉反向的换行(回车符),只保留正向的换行,所以输出的顺序是正确的。它还将任何空白的字符替换为制表符,这在处理 nroff(1) 和 tbl(1)的输出时非常有用。col从标准输入读取并写入标准输出。

-b, --no-backpaces
假设使用的输出设备不具备(光标)后退功能。在这种情况下,如果要在同一位置显示两个或更多的字符,在输出中只显示最后一个被读取的字符。

这正是我们想要的效果。我们用这个命令过滤之后再试一次:

# 将标准输出重定向到文件
root@localhost:~$ ossutil cp  oss://oss-bucket/software/example-desktop-11.0.0-win64-zip-chs.zip . | col -b > down.log
root@localhost:~$ ls -l down.log
-rw-r--r-- 1 root root 169 Jun 21 01:44 down.log # 只有169字符长了

root@localhost:~$ less down.log #查看文件内容,还是有些问题,但短了
Succeed:mTotalsnum: 1,0size:52,088,315,831.uOK num:K1(download61,objects).Progress: 60.750%, Speed: 42627.66KB/ss

average speed 143982000(byte/s)

14.504900(s) elapsed
down.log (END)

发现确实没有了中间过程,但输出的内容有些问题。真实的报告第一行应该是:

Succeed: Total num: 1, size: 2,088,315,831. OK num: 1(download 1 objects).                                        

猜测可能是空格没有得到妥善处理。在很多命令这个col -b是有效的,可能是这个ossutil的输出比较特殊?

方案五:放弃文件瘦身,能看到正确结果就行

直接将原始命令command > down.log,得到肥胖的文件,然后

cat down.log

我们就看到了仿佛在屏幕上执行的结果。因为我们的终端会正确处理所有文件中存储的控制字符。

关键词

stdout 标准输出 回车符 进度 日志文件 重定向 col命令

相关文章

  • NS3-sixth.cc

    把调试信息输出到文件里,自动输出 不要命令行cnwd输出到ascii文件里数据包输出到pcap文件里

  • C进阶1:文件操作

    0. 文件输入输出 使用printf()和命令行重定向>实现文件输出;使用scanf()和命令行重定向<实现文件输...

  • RH214|第五章 创建、查看和编辑文本文件

    将输出重定向到文件或程序 目标 完成本节内容后,你能够用shell重定向将输出或错误保存到文件中,并通过多个命令行...

  • golang同时输出到控制台和文件

    golang同时输出到控制台和文件 【已解决】go语言中实现log信息同时输出到文件和控制台(命令行)

  • gflags.h的用法

    命令行下使用: 输出: 也可以将命令行参数写进flags.txt文件

  • 01.C(Linux命令)

    (创建于2017/8/13) system命令(命令行) 文件管理 1)查看文件信息 ls 2)输出重定向>,一般...

  • 文件

    IO 从命令行输入字符输出ASCII值 读文件 二进制文件读取

  • 《ruby 教程》 ruby命令行与函数

    命令行参数 新建文件 hello.rb 执行 输出 读取文件 新建文件 read.rb 执行 逐行查找 新建文件 ...

  • linux 2>&1 &是什么

    linux常见输出到文件命令行,如:find /data -name 'login' -print > find....

  • Linux将输出的内容放到文件中存储

    如何把命令运行的结果保存到文件当中? 如何能在输出信息的同时把信息记录到文件中? 我们在上面的例子中可以看到,我们...

网友评论

      本文标题:命令行输出保存到文件时,如何清理命令行反复输出的进度信息给文件瘦

      本文链接:https://www.haomeiwen.com/subject/pkkyydtx.html