测试必会Linux实战:日志分析、服务排查与Docker容器操作
测试需要掌握的 Linux 操作系统知识我没有刻意去背命令而是被真实问题逼着学起来的。某个周五下午群里突然有人喊登录接口不通了你们谁有空看下我在本地 Windows 上试了试接口是通的但测试服务器上的服务确实报错。于是我熟练地打开终端ssh 登上测试机tail -f 看了下应用日志发现数据库连接池在凌晨批量任务后一直没有释放问题两分钟定位。类似场景我在不同团队里遇到过很多次。测试需要掌握的 Linux 操作系统知识从来不是要求你做运维专家而是让你在服务、日志、网络、环境这些高频战场上不用求人、不用瞎猜。这篇内容不会从内核原理讲起而是从测试工作的真实痛点出发把日志查看、服务排查、网络定位、权限环境、Shell 自动化、Docker 容器这些日常最高频的内容梳理一遍。适合刚接触服务器、或者已经在用但总靠搜索救急的测试同学。1. 每天都要面对 Linux测试离不开的四个场景1.1 你未必直接操作但问题总会找上你很多刚入行的测试同学觉得Linux 是开发和运维的事自己只要会点鼠标、会写用例就行。这个想法在一两个小项目里也许撑得过去但只要团队稍微正规一点测试就一定绕不开 Linux。被测系统部署在 Linux 服务器上日志在服务器上测试环境的重启、清理、数据准备往往也需要测试自己动手。再加上自动化测试任务大多跑在 Linux 的 CI 机器上跑挂了之后第一件事就是登录服务器看日志。你未必天天敲命令但一旦出问题命令行就是最直接的窗口。如果把系统比作一辆车测试不需要会造发动机但要会看仪表盘、会换备胎、知道哪个按钮管哪块面板。Linux 命令就是那块仪表盘。1.2 测试需要的不是操作系统原理而是一套高频命令集有不少初学者买来几百页的 Linux 教材从启动流程、内核模块、文件系统原理开始啃结果没坚持几天就放弃了。我个人的观点是测试需要掌握的 Linux 操作系统知识按工作场景来拆比按教材章节来学高效得多。你不需要现在就搞懂进程调度算法但你要会看某个服务到底还活着没有不需要深入理解虚拟内存但要会看磁盘是不是满了不需要精通网络协议栈但要能说清楚到底是哪一跳出了问题。下面这张表就是一个很好用的知识地图哪里卡住就学哪里测试高频场景对应能力典型命令查看运行日志日志分析tail、grep、less服务/进程排查进程管理ps、systemctl、top端口与网络定位网络排查ss、telnet、curl权限与文件操作用户与权限ls -l、chmod测试数据准备文本处理grep、sed、awk自动化重复操作Shell 脚本for 循环、crontab容器化环境Docker 操作docker ps、logs、exec磁盘空间清理存储管理df、du按这个路径走不用两个月就能应对绝大多数测试环境问题。很多同学觉得 Linux 难不是因为命令多而是因为不知道哪些命令值得先学。1.3 练习环境怎么搭千万别用生产环境练手学 Linux 最快的方式是拥有一台可以随便折腾的 Linux 机器。我最推荐的顺序是先在本地虚拟机里装一个最小化的发行版比如 Ubuntu Server 或其他主流服务器版2 核 4G 内存就够用装好之后马上拍一个快照。有了快照什么命令都可以大胆试。把系统搞坏了、把文件误删了恢复快照就能回到初始状态没有任何心理负担。等常用命令熟悉了再考虑买一台便宜的云服务器练远程登录和网络排障。还有一条路线是直接用 WSL 做日常练习它和真实服务器存在一定差异尤其是网络和 systemd 部分排查问题的时候要注意区分。这里有一个必须提醒的原则永远不要在生产环境练手也不要在其他同事正在用的公共测试环境里随便执行高危命令。练习环境的核心价值就是允许犯错而且能快速恢复。2. 日志分析基本功tail、grep、less 的实战组合2.1 别用 vim 打开几百 MB 的日志我见过不少测试同学遇到问题第一反应是 vim 打开日志。文件小的时候还好说一旦超过几百 MBvim 加载慢、翻页卡搜索的时候编辑器都快崩了。这不是你不认真而是工具选错了。日志文件天生适合把“结尾”作为阅读起点因为绝大多数报错都会出现在最近写入的部分。tail 命令默认显示文件最后 10 行tail -n 50 显示最后 50 行tail -f 进入实时跟踪模式持续输出新增内容排查线上问题最常用。日常最典型的操作是这样tail -n 200 app.log tail -f app.log | grep -E ERROR|Exception很多人以为 tail -f 只能干等输出其实它可以和 grep 组合这样不会在海量日志里被刷屏只保留自己关心的报错。如果还想看错误前后的相关日志再加上 -B 和 -A 参数分别控制匹配行之前和之后的行数。2.2 grep 过滤和二次过滤把日志缩小到能读的量日志分析的第二步是过滤。一个在线系统一天生成的日志可能几十万行直接看会看到怀疑人生。grep 的作用很简单只输出包含指定关键字的行。grep 最常用的几个参数值得记牢-n显示行号方便后续跳到具体位置-i忽略大小写适合搜关键字时不确定大小写-E使用扩展正则可以匹配多个关键字-A 5 和 -B 2输出匹配行之后 5 行、之前 2 行的上下文-v反向匹配把你不关心的行去掉。举个例子假设要查某天 10 点到 10 点 05 分之间订单接口的报错可以先用时间窗口过滤再搜业务关键字再筛异常级别grep -n 2025-06-01 10:0[0-5] app.log | grep 订单创建 | grep ERROR每次加一个 grep结果就会从几万行缩小到几百行、几十行后续阅读就轻松了。记住一个原则过滤比翻页更高效不要指望先把整个日志看一遍再找问题。2.3 less大文件阅读的默认选择如果说 tail 是用来“看尾巴”的less 就是用来在大文件里“游走”的。它与 vim 最大的区别是启动时不会把整个文件读进内存而是按需加载几百 MB 的日志也能快速打开。进入 less 之后按 / 输入关键字可以向下搜索n 跳转到下一个匹配位置Shiftn 跳转上一个G 跳到文件末尾gg 跳到开头输入数字再加 G 可以跳到指定行。如果按 F 键less 会进入类似 tail -f 的实时跟踪模式按 CtrlC 退出。我常用的操作流程是先用 grep 定位到错误行的行号回到 less 里输入“行号G”跳到附近再结合上下文阅读。这样既能快速定位又不会因为搜索模式太频繁而丢失上下文。grep -n 订单金额校验失败 app.log | head -5 less app.log # 在 less 内输入 1280G 跳到 1280 行附近2.4 日志切割、多日志文件和时间落点的判断排查历史问题时还有一个容易忽略的点日志切割。很多系统按天或按大小切割日志文件名可能是 app.log.20250601也可能压缩成 .gz。如果你只 tail app.log很可能只看到今天的片段历史问题就被漏掉了。这时候先做一步“侦察”ls -lt /data/logs/ find /data/logs -name *.log* -mtime -7ls -lt 会按修改时间倒序列出日志文件一眼就能看出哪个文件最近在写入再用 find 找到最近一周内生成或修改过的日志。如果日志切割配置没有通知进程重新打开文件进程还可能继续写入已经改名的旧文件导致新日志没有落到新文件里。遇到日志奇怪地不更新时先查一下进程实际打开了哪个文件再决定看哪个日志。3. 服务起没起、进程到底卡在哪环境排查三板斧3.1 第一步永远是服务到底活着没有测试群里只要有人说“环境挂了”不要急着找开发。先自己看一眼服务进程往往能省下半小时的沟通成本。两个高频命令systemctl status 服务名 和 ps -ef | grep 服务名。前者可以看 systemd 管理的服务状态、已运行时间和最近的日志片段后者可以看真实进程的命令行判断是不是启动参数不对导致进程行为异常。systemctl status api-server ps -ef | grep api-server ps -ef | grep java | grep -v grep最后一行里 grep -v grep 是个小技巧不加它的话连查询命令本身都会被匹配出来容易让人误以为有多个进程在跑。3.2 端口占用和“端口开着但连不上”服务启动失败时最常见的提示是端口被占用。查看端口监听用 ss 或者 netstatss -tlnp | grep 8080 netstat -anp | grep 8080看到 LISTEN 状态才说明端口真正在被监听。这里有个非常典型的坑同样是监听状态0.0.0.0:8080 和 127.0.0.1:8080 完全不是一回事。前者监听所有网卡外部机器可以访问后者只监听本机回环哪怕端口显示 LISTEN其它机器也连不上。联调环境里我踩过不止一次开发在服务器上 curl localhost 一切正常测试从另一台机器访问就是不通最后发现服务只监听了 127.0.0.1。访问前先确认监听地址能省下大量时间。如果确实需要释放端口fuser -k 8080/tcp 可以按端口杀掉关联进程。这条命令在测试环境可以用生产环境务必谨慎先确认进程归属再动手。3.3 CPU、内存和负载从现象到定位服务没挂但很慢也是测试的日常。top 是首选工具进入交互界面后按 P 按 CPU 排序按 M 按内存排序按 q 退出。如果想直接拿到文本结果做记录可以用top -b -n 1 | head -30 ps -eo pid,ppid,pcpu,pmem,cmd --sort-pcpu | head -20关于 load average 三个值很多新手会误解。它表示过去 1 分钟、5 分钟、15 分钟的平均负载不是 CPU 使用率。单核机器负载超过 1 说明任务排队多核机器负载 4 未必有问题要结合核数判断。如果怀疑是 Java 应用卡死可以再用 jstack PID 抓线程快照看线程是不是卡在锁或者数据库连接上。这部分不是测试的必备技能但至少要知道 JVM 自带的诊断工具可以辅助定位比自己瞎猜强。3.4 磁盘满了测试环境最容易被忽视的雷测试环境没人清理日志跑个把月磁盘就会被塞满。df -h 看分区使用率du -sh 目录名 看具体目录占用find 可以定位大文件df -h du -sh /data/logs find /data/logs -type f -size 200M清理日志时有一条很重要的经验如果文件正被进程写入直接 rm 文件后文件系统空间不会立即释放因为进程的文件句柄还指向那个已经删除的文件。更稳妥的做法是先清空文件内容再考虑删除或者配置日志轮转truncate -s 0 /data/logs/app.log如果已经手快 rm 了又发现空间没释放重启对应服务或者找到持有旧文件句柄的进程空间才会真正回来。4. 网络不通时测试如何快速判断是哪一端的锅4.1 网络排查的测试思维用证据链代替感觉出现访问故障测试报告里如果只写“网络不通”开发大概率会继续追问是域名解析不了是主机不可达是端口被防火墙挡了还是服务本身没响应网络排查的核心价值就是把“感觉”变成一组证据链。我的习惯是先跑一套固定顺序ping 判断主机可达性telnet 或 nc 判断端口连通性curl 判断应用层响应。越接近业务实际的命令越有说服力。ping -c 4 目标服务器IP telnet 目标服务器IP 8080 curl -v http://目标服务器IP:8080/api/health哪一步失败问题就出在哪一层报告也可以直接写到哪一层。4.2 ping 不通不一定代表故障很多测试同学一看到 ping 不通就慌了。实际上很多云主机默认禁止 ICMP 协议ping 不通是正常现象。更可靠的验证方式是用 curl 直接请求业务端口。curl 的几个常用姿势值得熟练掌握curl -v http://目标服务器IP:8080/api/health curl -I http://目标服务器IP:8080/ curl -X POST http://目标服务器IP:8080/api/login \ -H Content-Type: application/json \ -d {user:tester}curl -v 会显示域名解析、TCP 连接、TLS 握手、请求头、响应头全过程哪一段出问题一目了然。比如输出 connection timed out大概率是网络层问题输出 connection refused说明网络能通但端口没有监听如果 TLS 握手失败那又是证书或协议版本的问题。这些细节比一句“连不上”有用得多。4.3 telnet 测端口连不上也要看“拒绝方式”telnet 是最朴素的端口探测工具。执行后如果输出 Connected 并进入交互界面说明端口通如果 connection refused说明主机可达但目标端口没有服务监听如果一直卡住没有反应说明被防火墙静默丢弃了或者中间网络确实不通。nc 是更现代的替代方案nc -zv 目标服务器IP 8080这里有一个测试思维很关键拒绝和超时是两种完全不同的原因。拒绝说明服务没起来超时说明包可能被防火墙丢了处理方向完全不一样。如果服务器上安装的软件有限制也可以用 bash 自带的方式快速探测timeout 5 bash -c /dev/tcp/目标服务器IP/8080 echo open || echo closed4.4 hosts 文件、代理和 DNS 的坑测试阶段最常见的操作是改 hosts。坑也不少改完之后访问还是旧地址优先检查 HTTP_PROXY 和 HTTPS_PROXY 环境变量。很多终端里设置了代理curl 会走代理解析绕过代理再试curl --noproxy * -v http://api.test.local/v1/health排查域名解析是否生效用 dig 或 nslookup 看解析结果再对照 /etc/hosts 里的条目。有一点容易被忽略本机的 hosts 只对当前机器生效其它机器要访问同一环境需要各自配置 hosts或者走统一的内网 DNS 分配环境域名。不要在自己的机器上改了 hosts就以为全组人都能访问了。5. 权限、软链接与环境变量测试数据准备中的隐形地雷5.1 文件权限三连读、写、执行到底怎么影响测试测试日常中权限主要影响三件事能不能执行脚本、能不能读日志、能不能改配置。ls -l 输出的第一列像 -rw-r--r--第一个字符表示文件类型后面九位分成三组属主、属组、其他人。每组三位对应读 r、写 w、执行 x。最常用的权限操作其实就两个chmod x 给脚本添加执行权限chmod 644 设置标准文件权限。数字权限的计算规则是 r4、w2、x1加起来就是权限值。比如 754 表示属主拥有 rwx属组拥有 r-x其他人只能 r--。chmod x test.sh chmod 644 config.yaml测试环境里经常有人无论什么文件都 chmod 777图一时省事。这个习惯很不好一旦权限全开误删别人文件的时候连后悔的机会都没有。给脚本加执行权限就 chmod x不要动不动整个目录 777。5.2 软链接删错比读错更可怕软链接可以理解成快捷方式。ln -s 目标目录 linkname 创建之后ls -l 会看到 linkname - 目标目录访问 linkname 等于访问目标。这里有两个高频坑第一测试同学以为自己在改软链接指向的“副本”结果直接改了真实目录里的文件。改动之前先 ls -l 确认链接指向哪里。第二删除时写错路径。rm -rf linkname/ 末尾多一个斜杠含义可能变成删除目标目录里的内容非常危险。删除软链接更安全的方式是用 unlinkunlink linkname在测试环境里凡是涉及软链接的操作先看清指向再动手。5.3 环境变量、PATH 和 export 的生效范围刚配好 JDK 或 Node 环境新开一个终端却提示 command not found绝大多数情况是没配 PATH或者配置没有写进配置文件。export 只在当前 Shell 会话生效关掉终端就消失了。要长期生效需要把 export 写进 ~/.bashrc 或 /etc/profile再用 source 让当前会话立即加载echo export JAVA_HOME/opt/jdk17 ~/.bashrc echo export PATH$JAVA_HOME/bin:$PATH ~/.bashrc source ~/.bashrc which java配置 PATH 时有两点容易出错一是等号两边不要加空格二是 PATH 里多个路径用冒号分隔。很多脚本运行异常根源都是 cron 或远程执行环境里的 PATH 和交互终端不一样命令找不到。脚本里尽量写绝对路径能省掉非常多莫名其妙的故障。6. 用 Shell 脚本把重复操作打包成测试利器6.1 让终端自动干活把排查流程写成脚本很多人以为 Shell 脚本是运维才会的东西其实测试用来“偷懒”再好不过。你可以把反复执行的检查命令拼成一个脚本不用每次都背选项、敲长命令。下面这个脚本是我在实际项目中经常改用的模板保存成 check.sh然后 bash check.sh 执行#!/bin/bash # 日常环境自检脚本 echo 磁盘使用率 df -h / | tail -1 echo 服务进程 ps -ef | grep api-server | grep -v grep echo 端口 8080 ss -tlnp | grep 8080 || echo 8080 未监听 echo 最近 30 条错误日志 grep -E ERROR|Exception /data/logs/app.log | tail -30这类脚本不需要写得多花哨能稳定执行、每次输出均匀就好。换团队后改改路径和进程名就能接着用。6.2 变量、循环和退出码最精简的 Shell 学习包Shell 编程不需要一上来就学数组和一堆函数。先掌握三样东西变量、for 循环、if 判断就能覆盖大部分批量操作。下面这个例子是循环请求几个订单接口检查 HTTP 状态码#!/bin/bash BASE_URLhttp://127.0.0.1:8080/api for id in 1001 1002 1003; do code$(curl -s -o /dev/null -w %{http_code} $BASE_URL/order/$id) if [ $code 200 ]; then echo 订单 $id 正常 else echo 订单 $id 异常HTTP $code fi done这里的 curl 用 -s 静默模式-o /dev/null 丢弃响应体-w %{http_code} 只输出 HTTP 状态码。循环、判断、调用接口三样加起来已经能处理很多接口冒烟检查。还有一个基础概念要理解命令执行后的退出码 $?。为 0 表示成功非 0 表示失败。脚本里的 if 判断本质就是在检查命令的退出状态。6.3 用 crontab 跑定时任务测试数据清理的救命稻草测试环境的数据会越积越多手动清理很烦用 crontab 定时执行脚本是最省心的办法。crontab -e 编辑任务一行任务由五个字段组成分别表示分钟、小时、日、月、星期。比如每天凌晨 4 点执行清理脚本0 4 * * * /data/scripts/cleanup.sh /data/logs/cleanup.log 21清理脚本里可以做的事很多删除 7 天前的临时文件、清理测试订单数据、压缩旧日志。我踩过的坑是cron 里写相对路径执行时找不到命令因为 cron 环境的 PATH 比交互终端精简得多。正确做法是脚本内统一使用绝对路径同时把输出重定向到日志文件失败之后至少能知道发生了什么。7. 容器化时代的测试环境Docker 常见操作与认知误区7.1 Docker 不是黑魔法测试最常用到的三个命令现在测试环境越来越多地用 Docker 部署测试需要掌握的 Linux 操作系统知识里容器操作已经绕不开了。不过别怕日常高频命令并不多。最常用的是这三个docker ps # 查看运行中的容器 docker logs -f api-container --tail 100 # 查看容器日志 docker exec -it api-container bash # 进入容器内部进入容器后很多镜像是最小化安装vim、ping 都不一定存在这是正常的。没有 vim 就用 less 或者 cat没有 ping 就试试 curl实在不行用 docker cp 把文件拷出来再看。7.2 “容器里服务正常外面就是连不上”端口映射真相很多测试同学遇到过一种诡异情况docker exec 进容器之后 curl localhost 是通的但从宿主机访问就是不通。十有八九是端口映射没弄明白。docker run -p 8080:80 的意思是把宿主机的 8080 端口映射到容器内的 80 端口。如果服务在容器里监听 80宿主机访问 127.0.0.1:8080 才能通如果服务在容器里监听 8080那 -p 8080:80 就映射错了服务端口对不上。排查时第一步先看 docker ps 的 PORTS 列里面会显示宿主机端口和容器端口的映射关系。多个容器之间相互访问时要用 docker-compose 里定义的服务名或网络别名而不是 localhost。容器里的 localhost 指容器自己不是宿主机更不是对面那个容器。7.3 镜像和容器的关系别 rm 错对象镜像相当于模板容器是模板运行出来的实例。docker rm 容器名 是删除容器docker rmi 镜像名 是删除镜像。这两个命令看起来只差一个字母干的事情完全不同。测试同学压力测试后想清理磁盘空间经常一口气 rmi 一堆不用的镜像结果发现容器还在引用删除失败。可以先看内存和磁盘占用docker system df docker image prunedocker system df 能看到镜像、容器、缓存卷分别占了多少空间docker image prune 只清理悬空镜像相对安全。另外记住一点容器是临时状态。在容器里改了配置文件容器一旦被重新创建所有修改都会丢失。测试环境需要持久保存的修改要通过修改挂载目录或者重新构建镜像来实现不能只改容器内部。8. 三个月够用得上的自测清单与避坑总结8.1 一份可以直接对照的自测清单与其背命令不如准备一份“问题 → 命令 → 期望结果”的速查表。这里列一下我日常最高频使用的项目我需要知道什么命令示例当前时间date磁盘是否满了df -h目录占了多少空间du -sh /data服务进程是否存在ps -ef | grep 关键字端口是否监听ss -tlnp | grep 8080看实时日志tail -f app.log搜日志里的关键字grep -n 关键字 app.log请求一个接口看详情curl -v http://地址测端口通不通telnet 目标IP 端口看文件权限ls -l 文件给脚本加执行权限chmod x 文件查看当前环境变量echo $PATH把这些做成一份自己顺手整理的参考文档比啃半本教材更有价值。遇到不确定的命令查自己的速查本查不到再搜索。8.2 测试同学最容易踩的五个坑第一个用 vim 或者 cat 打开超大日志机器直接卡住。正确做法是 tail、grep、less 组合。第二个改了配置文件之后不重启服务然后反复怀疑自己改错了。改配置后要确认服务是否已经重启、日志是否加载了新的配置。第三个在终端里 export 一个变量新开会话后还是 not found。需要把配置写入 ~/.bashrc 并 source或者确认当前会话和脚本执行环境用的是同一个 PATH。第四个rm -rf 配合变量使用变量为空时可能变成危险操作。执行删除前先 echo 变量确认路径或者用 find 先找出目标再删。第五个只看当前日志文件忽略了按日期切割的历史日志。先 ls -lt 确认哪个文件在写入、哪个文件是目标时间段的记录。这些坑都不是命令有多难而是对 Linux 环境行为不够熟悉。踩过一次之后记住的效果比看十遍文章都牢固。8.3 学习路径的最终建议问题驱动顺便形成自己的速查本最后说点我个人的体会。带过不少新同学我发现学得最快的人不是把整本教材啃完的那种而是带着真实问题边查边用的那种。今天遇到的报错花十分钟搞清楚原理明天学的命令顺手写进自己的笔记后期遇到同类问题直接从笔记里翻答案。测试需要掌握的 Linux 操作系统知识不需要在第一天就全部掌握。先学会看日志、查端口、看进程、拷文件你就已经能应对至少一半的日常问题。等日常查询熟练了再去补 Shell 脚本和 Docker基本可以独当一面。别急着一天学完所有内容遇到问题再回来翻这篇文章效果反而更好。