我一直在用 both 的时候,周围就有同事问我:这俩到底有啥区别?我每次都是随便选一个用,感觉都差不多。说实话,如果你只是偶尔进个日志文件翻翻,可能真感觉不到区别。但当你在生产环境排查一个几 GB 的日志,或者写脚本处理文本流的时候,选错命令就真的会“卡”到你怀疑人生。
这篇东西我不会去抄 man page,就围绕大家最关心的几个点来聊:more 和 less 的核心能力差异、在管道和日志场景下的真实表现、以及我这些年实际使用中总结出的效率和踩坑经验。我会尽量把命令演示和背后的工作原理都说清楚,让你读完就知道什么场景该用哪个,并且能避开我当初踩过的那些坑。
1. 这俩命令的“出身”和设计哲学差异:为什么会有 two 个功能类似的工具
先来点背景,这有助于理解它们后续所有的行为差异。more 的诞生时间非常早,是 BSD 系统里的老牌工具,它的名字已经说明了它的设计逻辑,就是“再多给我一屏”(give me more)。在那个终端还比较原始、内存资源也紧张的时代,more 的设计目标非常朴素:把一个比较长的文本,一屏一屏地显示出来,看完一屏按空格再往下看,仅此而已。
而 less 呢,是 1983 年到 1985 年间,由 Mark Nudelman 写的。它的名字很有意思,它是一种反讽式的命名——“less is more”(少即是多),但实际功能却比 more 多了太多了。less 的口号也就是“opposite of more”。它的出现,其实是为了突破 more 的种种局限,尤其是 backwards(往回翻)、search(搜索)这些在 more 里不太好用或者压根没有的能力。
所以你可以这样理解:more 的设计哲学是“够用就好”,它的代码体量和内存占用都非常小,行为非常直接;而 less 的设计哲学是“在终端里塞进一个完整的文本查看器”,它要提供接近 Vim 那样强大的浏览和搜索体验,但比 Vim 简单多了,不需要记住一堆编辑命令。
这个设计哲学的差异,直接导致了一个很核心的区别:more 通常只能向前翻(少部分实现支持向后一点点),less 则可以随便前后翻,而且翻页极其流畅。很多刚从 Windows 过来、或者新手教程只教了 more 的运维朋友,第一次用 less 第一次按上下箭头能往上翻时,都会有一种“这才是人用的工具”的感觉。
从技术实现角度再拆细一点,两者的底层处理逻辑也不一样。more 的经典实现,是读取文件内容后放到缓冲区,然后按终端高度输出,整个过程中交互状态相对简单。less 则维护了一个更复杂的缓冲区状态,它需要支持行号跟踪、搜索高亮、多文件切换、标记位置等高级功能,所以它在启动时可能会花更多内存来处理大文件,但也正是这份内存换来了无比流畅的回滚和搜索体验。
注意:这里说的技术实现是基于我这些年使用 GNU 工具链和主流 BSD 系统的经验归纳的,不同发行版或 Unix 系统里的 more / less 版本行为会有细微差异。比如在部分 Solaris 上,more 的向后翻支持就很弱,而 Linux 上很多发行版已经把 more 指向了 util-linux 的实现,能力会强一些。但不管具体实现怎样,more 整体上仍是“简化版”,less 是“增强版”这条主线没有变。
2. 分屏与回卷能力实测:为什么说 less 是“可以直接淘汰 more”的第一步
我第一次意识到这俩命令是“两个时代的产品”,是在一次排查线上日志的时候。当时日志疯狂输出,我习惯性地敲了more app.log,结果发现日志刷得太快,我根本来不及看,而且当我试着按上箭头想回退看刚才的报错时,屏幕上毫无反应。那一刻我很崩溃,因为我记得当时用 less 是能回滚的。也是从那次起,我彻底转投 less 阵营,再也没用 more 看过超过一屏的文件。
在分屏和回卷这块,我做了一组对比测试,大家可以直接抄作业:
| 操作 | more 的表现 | less 的表现 |
|---|---|---|
| 查看下一屏 | 空格键(非常顺手) | 空格键或 f 键、Ctrl-F |
| 查看上一屏 | 大多数版本不支持,部分版本(如 util-linux 的 more)支持 b 键,但行为比较蹩脚 | 直接按 b 键或 Ctrl-B,非常流畅 |
| 向下逐行滚动 | 只有回车键(逐行向下),且频率很慢 | 直接按 j 键或向下箭头,连续滚动非常顺滑 |
| 向上逐行滚动 | 无(除非是较新的实现,比如部分发行版的 more 支持方向键,但我遇到过的更多是不支持或体验极差) | 直接按 k 键或向上箭头 |
| 跳转到文件开头/结尾 | 无 | g 跳到开头,G 跳到结尾 |
| 查找关键字 | 支持/keyword,但是不支持高亮,或者高亮效果非常一般 | 支持/keyword,并且高亮命中,n/N 循环跳转 |
从这个表格能看出来,more 的设计目标是“给你看完下一页”,less 的设计目标却是“让你随心所欲地在文本里漫游”。如果你平时需要查看的文本都在一屏以内(比如ls -l输出几乎不超过一屏),那用 more 还是 less 确实无所谓。但只要文件一长、需要反复上下对比着看,less 的体验优势就立刻体现出来了。所以,我在工作里的习惯是:只要内容可能超过一屏,我 100% 用 less,因为我不想为了 more 的那一点点内存占用省事而浪费我的时间。
这里还有一个大家容易忽略的细节是,less 支持按百分比定位。你打开一个日志文件后想快速看 50% 的位置,直接按50%(先输入数字 50,再按百分号)就能直接过去,这在分析几万行的日志时非常有用。more 里虽然也有类似“跳到指定行”的命令格式(通过+行号启动),但交互式地在文件内部跳转,就没有 less 这么方便了。
3. 搜索与高亮机制:排查日志时,这就是天壤之别
分析日志、查报错、核对关键字是做运维和开发的日常。在这个场景下,more 和 less 的差距可以说是天壤之别。我记得我初学 Linux 的时候,用 more 查看日志,发现有 ERROR 字样,第一反应是“哦,我看到了一处,我按空格往下翻,慢慢找”。那时候不懂事,不知道还有什么搜索功能,纯靠肉眼硬翻。直到后来有人告诉我,less 里输入/ERROR回车,所有匹配的 ERROR 都会高亮,按 n 直接跳到下一个,我的效率瞬间提升了一个档次。
但搜索这件事也不能只看高亮,less 的强大在于搜索状态的管理。比如:
- 搜索后跳转:在 less 中输入
/关键字,回车后会自动跳到第一个匹配的位置;按n继续下一个,按N回退上一个。 - 反向搜索:按
?关键字就能从当前位置向上搜索,这在日志特别长、你刚才看到一处但现在想再往上看时非常实用。 - 高亮记忆:只要你不清空搜索高亮,匹配的内容会一直高亮显示,即使你前后翻了很久,高亮依然有效。而 more,同时支持
/搜索是有的,但高亮基本聊胜于无。 - 搜索的模式:less 默认是区分大小写的,但你可以用
-i参数启动,或者直接搜索时用/关键字/i的语法来忽略大小写。这对查日志里大小写不规则的英文非常实用。
对比 more 的搜索,我结合实测经验来说:more 在多数实现里支持/关键词搜索,但搜索结果只是定位,没有高亮;而且它只会往当前位置之后找,找到后不能通过 n/N 继续循环查找。部分系统的 more(例如 util-linux 版本)其实也支持 n/N 循环搜索,但很多老 Unix 系统或精简环境里的 more 反而没有这个功能。所以如果你在脚本或者在线排查中不确定环境里的 more 具体是哪个版本和实现,最好别依赖它的搜索循环能力,用一个可以直接依赖的 less 会稳妥得多。
还有一个可以明显提升效率的点:less 支持搜索时的正则式。比如我经常在日志里找多个关键字的组合,就直接用/(ERROR|FATAL|Exception)这样的正则表达式,一下能命中所有相关异常。这在 more 里就很难实现。对于分析日志来说,这种“一次命中多个模式”的能力真的太重要了。
在这里附上一个我个人的避坑经验:如果你用 less 搜索后发现匹配项没有高亮,先检查一下是不是设置了
-G(去掉高亮)之类的参数,或者你的 TERM 环境变量有问题。有时候在 tmux 或 screen 会话里,less 的高亮会因终端的 terminfo 配置而失效。可以用TERM=xterm-256color来重新设置后再打开 less,通常能解决。
4. 性能与大文件表现:为什么看超大的日志我更推荐 less
有人可能会想,more 更轻量,看大文件是不是 more 更快更稳?我的实测结论是:事情没这么简单。more 在打开超大文件时确实启动极快,因为它可能压根没有建立全套的行索引结构,整体内存占用也更低。但这种低内存换来的后果是,当你尝试在 more 里做“向上回卷”时,部分实现会把你打回原形:或者完全不响应,或者重新从文件头开始再走一遍,那个体验真的可以用灾难来形容。
less 呢,启动时会做更多初始化,比如建立缓冲区映射和行状态信息。所以单纯看“打开文件”这个动作,less 可能比 more 慢那么一会儿(其实对于机械盘时代的旧版本慢得明显,现在固态硬盘时代几乎感觉不到)。但一旦文件打开之后,来回翻页、搜索、跳转,less 都要高效得多,尤其是在配合-S参数处理长行日志时。
说到长行日志,这一点值得单独拎出来讲。很多业务日志是单行很长的 JSON 或带堆栈的文本,若不处理,当作普通文本打开会被自动折行(wrap),看起来非常乱。more 和 less 都有处理方式,但我不太用 more 来做这种场景,因为它的控制选项不够细。less 可以用-S参数让超长行不折行,而是横向滚动显示,这样日志里的字段结构就一目了然了。在 more 里,虽然也有类似的控制能力,但总体上没有 less 的滚动手感好。比如 less 里可以直接用左右方向键或者h/l横向滚动,而 more 里的横向滚动逻辑就尴尬很多。
大文件的另一个痛点就是搜索。less 搜索大文件时,虽然第一次搜索需要扫描全文,但它会记住匹配结果,后续在全文范围内反复跳转都很快。而 more 的搜索,我印象里每次搜索都不够智能,部分实现搜索后无法回到搜索前的位置,或者搜索过程容易卡顿。所以如果让我对一个几十 MB 的日志做深度排查,我无脑选 less。
偶尔会有极端情况:文件接近几个 GB,机器内存又很紧张。此时 less 的全功能加载策略可能会让内存有点吃紧,但这不代表 more 就更适合。在这种机器上,更好的方案是用tail、grep等工具先过滤,再用 less 去查看过滤后的结果,而不是拿 more 硬扛一个巨型文件。我见过有人在几 GB 的日志上直接more /var/log/xxx.log,然后终端完全卡死,最后只能 Ctrl-C 强制退出。这个教训可以记住:当文本大到一定程度,查看器本身的功能高级与否已经不重要,重要的是你的工作流要合理(比如先 grep 出关键行再查看)。
5. 管道与交互边界:more 常用于“伪交互”,less 却接管了整个终端
在日常使用中,很多命令的输出是很长的,比如ps aux、systemctl status、dmesg。我们经常会顺手把它管道给 more 或 less,例如dmesg | more。这两种方式看起来行为差不多,但实际交互逻辑有区别。
more 在管道模式下的处理策略相对简单,它在读完当前屏内容后显示“--More--(xx%)”等待你的操作,整个过程中它更像一个“分页器”,一次从一个数据流里读取一块显示一块,交互相对轻量。less 在管道模式下,会先把整个输入数据读取到缓冲区,然后再进入交互模式,所以如果输入源特别大(比如一个无限日志流),less 一开始可能就会不断读数据,直到把所有输入都读进缓冲区才进入可交互状态。这意味着如果你往 less 里管道一个无限输出的命令,它可能永远卡在读取阶段而无法展示内容。
这个点我用一个很具体的场景来解释:我在写一些自动化运维脚本时,如果要让机器“根据实际内容”来做判断,more 和 less 都不合适,应该直接用 grep/awk/sed 去解析文本,而不是进入交互模式。但如果我在手动排查问题,比如把journalctl -u myservice --since today | grep -i error | less,这种经过 grep 过滤后的结果,用 less 是完全没有问题的,因为输出量已经被 grep 控制住了,不会出现无限流。但是如果你直接journalctl -f -u myservice | less,这个-f是持续输出的日志流,less 可能会一直读下去不给你交互的界面(因为数据源没有结束),甚至到最后你看到的是零散内容或者一个失控的账单。more 在这个场景其实也好不到哪儿去,因为它也拿不到一个明确的文件结尾。正确的做法是用journalctl -f时直接看终端输出,或加--no-pager配合 grep,而不是接 less 或 more。
从这个点能看出 more 和 less 的边界:more 适合简单的“看完即走”的管道输出分页,不需要记住或回溯;less 更适合需要深入分析、反复查阅的文件或者有限输出文本,所以我在写博客或处理文档时,会特意用 less 打开文本文件来定位特定段落,因为它的交互能力和状态保持能力更符合“编辑器式”的阅读需求。
这里特别需要一个提醒:在脚本中使用 less 或 more 时,它们的行为会受
-F(如果内容一屏能显示完就自动退出)等参数的影响。less 带有-F参数,在管道输出很短时直接退出,不会出现“卡在 More 提示符”里的情况,这对自动化处理是很友好的。而 more 在很多实现下遇到内容较短时也会直接退出,但行为并不完全一致。写管道相关脚本时,一定要测试好具体环境下的行为。
6. 实操经验:从入门到常用的进阶命令组合与避坑指南
经过前面几轮分析,结论其实已经很明显:现代工作流中,less 是更强大的选择。但这不代表 more 就毫无用处。在绝对精简的嵌入式环境、容器镜像里的精简用户态、或者恢复模式中,有时候可能只有 more 而没有 less,所以 more 的基本操作还是得会一点。
我自己的命令行习惯是分三层来做文本浏览的:
- 小文本且不打算细看(比如命令帮助不算长、文件很短):直接 cat,不接分页。
- 中等长度文本或日志(几十行到几百行):直接 less,因为随时可能搜关键字、上下翻。
- 超大文件排查(几百 MB 以上):先用 grep、awk、sed 等工具过滤出我要的范围,甚至把关键行重定向到临时文件,然后再用 less 打开临时文件,或者用 less 直接打开原文件加搜索模式。
考虑到很多朋友可能刚开始接触这些命令,我把最常用的几个 less 参数和操作整理成一个速查表,大家可以打印出来贴到工位上:
| 命令/按键 | 作用 | 使用频率 |
|---|---|---|
less file | 打开文件 | 超高 |
less -N file | 打开文件并显示行号 | 高,查日志时几乎必用 |
less -S file | 超长行不折行,横向滚动 | 高,查 JSON 日志神器 |
less -i file | 忽略大小写搜索 | 中 |
/keyword | 正向搜索 | 超高 |
?keyword | 反向搜索 | 中 |
n/N | 下一个匹配 / 上一个匹配 | 超高 |
g/G | 回到文件开头 / 文件末尾 | 高 |
F(大写) | 类似tail -f的跟随模式 | 高,跟踪实时日志很舒服 |
-S(在 less 内部按) | 切换是否折行 | 高 |
v | 用系统默认编辑器打开当前文件 | 中(编辑时用) |
50% | 跳转到文件 50% 位置 | 中 |
让我单独说说less +F这个模式。这是 less 里一个很常用的隐藏能力,相当于“内置了 tail -f”。以前排查实时日志,要么开两个终端,一个 tail -f 跟踪,一个 less 慢慢翻;或者干脆关掉 tail 再打开 less。其实 less 里直接按大写F,它就会进入“跟随模式”——文件有新内容就自动滚动,和 tail -f 一样。想退出跟随模式返回静态模式,按Ctrl-C就行了。这个功能在调试服务、观察日志时实在是太顺滑了,我基本已经不用单独的 tail -f 来看日志,都是 less + F 一把梭。
还有一个小技巧:less 支持同时打开多个文件,比如less file1 file2 file3,然后用:n跳到下一个文件,:p回到上一个文件。这在前后对比多个日志片段时很方便。比如我排查一个接口调用链,往往要把入口日志文件、中间件日志、DB 日志一起打开,这时less log1.log log2.log log3.log,来回:n、:p,非常省事。more 当然也支持多文件,但切换的逻辑就没有 less 直观。
踩坑方面,我再补几个比较常见的。
一个坑是环境变量 PAGER 的影响。很多命令工具(比如git log、man、systemctl)会读取PAGER或MANPAGER环境变量来决定用什么分页器。如果你在.bashrc里设置了export PAGER=more,那么你用git log时可能就进入 more 的交互,从上面分析知道,往回翻大概率会遇到麻烦。所以我个人建议,除非你明确知道自己在做什么,否则把 PAGER 设置成 less 会好很多。我自己就吃过这个亏,当年为了“轻量”把 PAGER 设为 more,结果后来 git log 翻页时往回翻不了,排查了半天才发现是这个变量作怪。
另一个坑是管道输出给 less 时,退出 code 是 0 的问题。在写某些脚本时,如果用less作为分页器,用户按 q 退出后管道的退出码会被吞掉,变为 0,这会导致脚本误判。more 也存在类似的情况。所以在自动化脚本里如果需要严格判断上游命令的成功与否,不要依赖 less/more 的返回码,应当通过set -o pipefail或者在管道前单独判断上游命令的退出码。比如ps aux | grep nginx || echo "no process"这种写法,千万不要写成ps aux | grep nginx | less后去判断$?。
还有一个容易忽视的坑是less 的-X参数。如果你的 TERM 环境变量比较特殊,或者你在某些 CI 系统里调用 less,遇到清屏问题时,试试less -X,它会禁止“退出时清屏”的动作,也就是在 less 里按 q 退出后,屏幕上依然保留当前内容,不会黑屏或滚动回命令提示行。很多人说“less 退出后内容全没了”,其实大多就是这个清屏行为导致的,理解了-X就能控制它。
7. 结合场景的选型建议和面试高频问题参考
聊到这里,可能有人会问:那我是不是彻底不学 more 就行?我的建议是:基础了解 more,主学 less。more 只需要掌握“空格下一页、回车下一行、q 退出”这三点,就足够应急了。毕竟在某些极端精简环境里可能没有 less,但一般都会带一个 more。用 more 应急时,思路就是“只往后看,别想着回头”,错过了就错过了,我们后续再用 grep/sed 去查。
less 则要花点心思系统学一学,因为它的能力远不止“翻页 + 搜索”。比如我上面提到的less -S、less +F、多文件模式、标记跳转(m标记、'跳到标记处)等,每个能力在特定场景都能帮上大忙。特别是做日志分析的时候,less 配合 grep、awk、sort、uniq 这些命令,能构建一套非常高效的排查链路。
关于当前非常火的面试题参考,因为网络热词里出现了很多 Linux 面试相关词汇,我也顺手梳理几个常见面试问法和参考回答方向,方便大家自查:
- Q:more 和 less 的主要区别是什么?A:less 是 more 的增强版,除了支持更多翻页方式还支持回卷、搜索高亮、跳转、跟随文件等高级功能。more 更轻量但交互能力弱。
- Q:如何让 less 像 tail -f 一样跟随文件输出?A:用
less +F或者在 less 内按大写F。退出跟随模式按Ctrl-C。 - Q:less 中如何忽略大小写搜索?A:命令行加
-i参数,或者搜索时使用/keyword/i。 - Q:在管道中使用分页器时,如何避免破坏上游命令的退出码?A:使用
set -o pipefail,或者在管道前单独判断上游命令的退出码。 - Q:怎样在 less 中显示行号?A:启动参数加
-N,或者在 less 内部输入-N切换。 - Q:如果你想快速查看一个超大日志文件中的特定关键字,怎么做最高效?A:先 grep 过滤关键字,再 less 查看结果;或者直接 less 打开后
/keyword搜索。因为 less 打开超大文件后,搜索依然很快,但不建议在超大文件里来回翻页做人工定位。
这类面试问题我在给新人做培训时也经常问,目的就是考察他是不是真在命令行里工作了足够的时间。如果一个人能脱口而出less -N和/keyword,并且能解释为什么在高频日志分析场景选 less 而不是 more,那至少说明他平时不是在“背命令”。
最后再分享一个我自己操作中的体会:区分一个命令是否优秀,要看它在异常场景下的应变能力。more 在我需要向回翻时给我的只有沉默;less 则给了我完整的回溯、搜索、标记、跟随能力。这种“被工具兜底”的安全感,在工作效率提升上是实打实的。希望这篇文章能帮大家彻底理清 more 和 less 的差异,也欢迎在评论区分享你用 less/more 时遇到过的好用技巧或奇葩坑,咱们一起把这些命令玩得更溜。