【问题标题】:"less" consumes lots of RAM for a piped output on gzipped file, why?“少”消耗大量 RAM 用于 gzip 文件的管道输出,为什么?
【发布时间】:2015-04-04 18:38:34
【问题描述】:

请原谅我无用的 catecho 前期,但是在 ~2GB .gz 文件上运行 less 时,我看到 ~25GB 的 RAM 被消耗(尽管输出被管道传输到 awk 并在那里消耗) ):

[user@mybox:~]$ cat <(echo '173abcde7665559.90651926
131abcde7298936.49040546
... (25 lines total here) ...
186abcde4858463.43044639
163abcde9409643.80726489'|awk '{print "KEY 1"length($1)-16":"$1}';
less /tmp/stats.gz)|awk '{if("KEY"==$1){K[$2]=1}else{if($8 in K)print}}' >bad25&

我预计上面的内容不需要任何 RAM 就可以完成,但令我惊讶的是,它在大约 2.5 小时后的样子(到 89.8% 读取 .gz 时):

[user@mybox:~]$ ps auxf|grep -e 'pts/2' -e PID |grep -v grep
USER   PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
user 26896  0.0  0.0  68356  1580 pts/2    Ss+  15:23   0:00  \_ /bin/bash
user 27927  0.7  0.0  58932   476 pts/2    S    15:23   1:00      \_ cat     /dev/fd/63
user 27929  0.0  0.0  68356   716 pts/2    S+   15:23   0:00      |   \_ /bin/bash
user 27932 99.9 75.0 22389852 18512388 pts/2 R+ 15:23 137:42      |       \_ less /tmp/stats.gz
user 27933  0.0  0.0  65928  1168 pts/2    S+   15:23   0:00      |           \_ /bin/sh - /usr/bin/lesspipe.sh /tmp/stats.gz
user 27934  1.3  0.0   4176   492 pts/2    S+   15:23   1:52      |               \_ gzip -dc -- /tmp/stats.gz
user 27928  2.1  0.0  63908   776 pts/2    S    15:23   2:56      \_ awk {if("KEY"==$1){K[$2]=1}else{if($8 in K)print}}
[user@mybox:~]$ free -m
             total       used       free     shared    buffers     cached
Mem:         24103      23985        117          0        125       3958
-/+ buffers/cache:      19901       4201
Swap:         8191       7914        277
[user@mybox:~]$ echo 1|awk "{print `cat /proc/27934/fdinfo/3|sed -n 's/pos:[ \t]*//p'`/`du -b /tmp/stats.gz|sed 's/[ \t].*//'`}";date
0.898284
Sat Apr  4 17:41:24 GMT 2015

我会尝试一些其他选项(例如直接使用 gzip -dczcat 重写我的命令),看看是否有帮助,但如果有人可以让我知道为什么会在使用 less(或任何其他命令)时发生这种情况),是否是已知的lessbash 在更高版本中修复的错误?也许一些 shell 技巧可以强制 less 正常运行?

附: stats.gz 是 25261745373 字节未压缩(5 次环绕 MAX_INT):

[user@mybox:~]$ ls -l /tmp/stats.gz
-rw-r--r-- 1 user users 1837966346 Apr  3 21:42 /tmp/stats.gz
[user@mybox:~]$ gzip -l /tmp/stats.gz
         compressed        uncompressed  ratio uncompressed_name
         1837966346          3786908893  51.5% /tmp/stats

【问题讨论】:

  • less 旨在以交互方式使用。看来它的输出在这里通过管道传输到 awk 中。你为什么还要使用less
  • 只是一个“无害”的习惯(在今天的启示之后就不是那么无害了)。使用正确的lesspipe设置 - 无需关心它是gz / bz2 / etc还是原始文件(有大量IT强制例程用于gzipping / bzipping所有比1d更早的东西)

标签: linux bash shell gzip less-unix


【解决方案1】:

less 将所有数据存储在内存中。这就是允许您向上滚动的原因。

【讨论】:

  • 谢谢,听起来很合理。所以less 不够“聪明”,无法看到输出进入管道(而不是进入可滚动的 tty)并因此丢弃内部缓冲区?
  • 显然不是。可能有配置这些东西的选项,但如果您不想分页,则不应该使用分页器。
  • 好的,谢谢!是时候改变我的习惯并使用直接工具而不是我以前使用的工具,而不会注意到任何开销:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 2020-01-22
  • 2011-05-10
  • 1970-01-01
相关资源
最近更新 更多