3. Linux日志查看基础命令:cat、less、more、head、tail、grep的基础用法,以及管道符组合使用
日志排查,说白了就是跟文件内容打交道。你拿到一台服务器,第一件事往往是看看日志里有什么异常。这时候,几个基础命令就是你的左膀右臂。我个人习惯把这几个命令分成两类:一类是「把内容倒出来给你看」,另一类是「在内容里翻找你要的东西」。今天咱们就把它们挨个捋一遍。
核心思路:日志文件可能很大,也可能很小。小文件直接看,大文件要分段看,关键信息要过滤看。掌握这几个命令,你就能应对90%的日志查看场景。
3.1 cat:简单粗暴,全量输出
cat 是「concatenate」的缩写,意思是连接文件并输出。最常用的场景就是看小文件。比如你刚部署完一个服务,想确认启动日志有没有报错:
cat /var/log/app/startup.log
嗯,这里要注意——cat 会把文件内容一股脑全吐到屏幕上。如果文件有几百兆,你的终端会直接卡死。我在项目中遇到过一位同事,用 cat 看一个 2GB 的日志文件,结果 SSH 会话直接断掉,不得不重启终端。所以我的建议是:文件超过 50 行,就别用 cat 了。
不过 cat 有几个实用的小参数:
-n:显示行号。排查问题时,行号能帮你精确定位。-b:只给非空行编号。看代码时更清爽。-A:显示所有不可见字符,比如换行符、制表符。有时候日志里混了特殊字符,肉眼看不出来,用这个就能现原形。
cat -n /var/log/syslog | tail -20
你看,我习惯把 cat 和 tail 组合起来用,只输出最后 20 行带行号的内容。这就是管道符的魅力,后面会细说。
3.2 less 和 more:翻页查看,大文件克星
当年我刚入行时,前辈跟我说:「看大文件用 more,但真正的高手用 less。」为什么?因为 less 是 more 的增强版,功能更强大。
more 只能往下翻,看完就退出。而 less 可以上下翻,还能搜索。你想想看,排查日志时经常需要来回对比,less 显然更顺手。
我常用的 less 操作:
- 上下翻页:
PageUp/PageDown,或者j/k逐行移动。 - 搜索:输入
/关键词向下搜索,?关键词向上搜索。按n跳到下一个匹配,N跳到上一个。 - 跳转到指定行:输入
1000g直接跳到第 1000 行。 - 实时查看:按
F键,less会像tail -f一样持续跟踪文件末尾的新增内容。按Ctrl+C退出。
less /var/log/nginx/access.log
# 进入后输入 /404 搜索所有 404 错误
我的小技巧:用 less 打开日志后,先按 G 跳到文件末尾,再按 ? 向上搜索「ERROR」或「Exception」。这样你能看到最近发生的错误,而不是从头翻到尾。
至于 more,我现在几乎不用了。除非是在某些嵌入式系统里,less 没装,才用 more 凑合一下。
3.3 head 和 tail:只看头尾,精准定位
日志文件通常按时间顺序追加,最新的内容在末尾。所以 tail 是我排查问题时用得最多的命令。
head:看文件开头
比如你想确认日志文件的格式是否正确:
head -5 /var/log/messages
默认显示前 10 行,-n 参数可以指定行数。我偶尔用它来检查配置文件的开头部分,比如 Nginx 的 nginx.conf 第一段是不是 worker_processes。
tail:看文件末尾,实时追踪
这才是日志排查的利器:
tail -100 /var/log/app.log # 看最后 100 行
tail -f /var/log/app.log # 实时追踪新增内容
-f 参数是「follow」的意思,它会持续输出文件的新增内容。我在项目中遇到过一个问题:服务突然挂了,但日志里没有明显报错。我用了 tail -f 盯着日志,然后手动触发服务重启,果然看到了一闪而过的 OOM(内存溢出)信息。如果不实时追踪,这条关键日志就被刷掉了。
避坑指南:我曾经在排查问题时,用 tail -f 看了半天,发现日志没更新。后来才意识到,日志文件被 logrotate 轮转(重命名)了,tail -f 还在盯着旧文件。正确的做法是用 tail -F(大写 F),它会跟踪文件名,即使文件被轮转也能自动切换到新文件。
3.4 grep:日志排查的灵魂
如果说前面几个命令是「怎么看」,那 grep 就是「怎么找」。没有 grep,你只能肉眼在一堆日志里翻找,效率极低。
我常用的 grep 参数:
| 参数 | 作用 | 示例 |
|---|---|---|
-i |
忽略大小写 | grep -i "error" app.log |
-v |
反向匹配,排除某些行 | grep -v "INFO" app.log |
-n |
显示匹配行的行号 | grep -n "500" access.log |
-c |
统计匹配的行数 | grep -c "ERROR" app.log |
-A 5 |
显示匹配行及其后 5 行 | grep -A 5 "Exception" app.log |
-B 5 |
显示匹配行及其前 5 行 | grep -B 5 "OOM" app.log |
-C 5 |
显示匹配行及其前后各 5 行 | grep -C 5 "timeout" app.log |
-E |
启用扩展正则表达式 | grep -E "ERROR|FATAL" app.log |
举个例子,你想看某个时间段内的错误日志:
grep "2024-01-15 10:3[0-9]" app.log | grep -i "error"
这里用到了管道符,把第一个 grep 的结果传给第二个 grep 继续过滤。你想想看,如果没有管道,你得先把结果存到临时文件,再读进来过滤,多麻烦。
核心技巧:排查问题时,先用 grep -c 统计一下错误出现的频率。如果某个错误出现了几千次,那大概率是系统性问题;如果只出现一两次,可能是偶发异常。这个判断能帮你快速确定排查方向。
3.5 管道符组合:把命令串起来
管道符 | 是 Linux 的哲学核心——「每个命令只做一件事,但组合起来无所不能」。它的作用很简单:把左边命令的输出,作为右边命令的输入。
我常用的组合套路:
- 过滤 + 分页:
grep "ERROR" app.log | less - 过滤 + 统计:
grep "500" access.log | wc -l - 过滤 + 排序 + 去重:
grep "ERROR" app.log | awk '{print $5}' | sort | uniq -c | sort -rn - 实时过滤:
tail -f app.log | grep --line-buffered "ERROR"
这里有个坑要注意——grep 默认有缓冲区,在管道里可能不会实时输出。加上 --line-buffered 参数,就能每匹配到一行就输出一行。我曾经因为这个坑,在排查线上问题时,等了半天没看到输出,还以为服务没报错,结果其实是缓冲区没刷新。
再分享一个我常用的「三板斧」:
# 第一步:看最近 1000 行日志里有没有错误
tail -1000 app.log | grep -i "error"
# 第二步:如果有,看错误前后的上下文
tail -1000 app.log | grep -i -C 5 "error"
# 第三步:统计错误类型
tail -1000 app.log | grep -i "error" | awk '{print $5}' | sort | uniq -c | sort -rn
这三步走下来,大部分问题的根因都能定位到。
3.6 知识体系总览
下面这张图,是我自己总结的日志查看命令体系。你可以把它当成一个「操作地图」,遇到问题就知道该用什么命令组合。
这张图的核心逻辑是:先确定你要看什么(全量、头尾、还是过滤),然后选对应的命令,最后用管道符把它们串起来完成复杂任务。说白了,就是「分而治之,组合制胜」。
我的建议:别死记命令参数。你只需要记住每个命令能干什么,具体参数忘了就查 man 手册。真正重要的是「组合思维」——知道什么时候该用 tail,什么时候该用 grep,以及怎么把它们串起来解决问题。
好了,这一章的内容就到这里。这几个命令虽然基础,但用好它们,你就能在日志的海洋里快速找到那根「针」。下一章咱们会聊更高级的日志分析技巧,比如用 awk 和 sed 做文本处理,敬请期待。