☰
Linux高频命令实战指南:文件文本处理与系统排查技巧
2026/10/15 4:53:05 网站建设 项目流程

用过几年 Linux 的人多少都有这种体会:命令本身不难记,难的是在真实的运维和开发场景里知道该用哪一条、怎么组合、踩过的坑在哪里。这篇文章想做的不是把 man 手册抄一遍,而是把日常最常用的 Linux 命令按场景拆开讲清楚,每个命令都配上实际工作中会用到的参数和组合方式,以及我自己的使用习惯和踩坑记录。适合刚接触 Linux 的初学者,也适合已经能干活但想补一补基本功的开发者。

我尽量不堆砌那种“命令 + 参数表”的干巴巴写法,而是把命令放进真实场景里说。比如排查服务器卡顿、查找日志里的报错、处理权限拒绝、确认端口被谁占用——这些才是大家真正会遇到的诉求。

1. 文件与目录操作:每天用最多,也最容易疏忽的地方

1.1 ls、cd、pwd:看似简单,几个参数能救命

ls是大多数人接触的第一个命令,但很少人把它用全。日常开发中我几乎固定用ls -lah,这个组合会列出所有文件(包括隐藏文件)、带单位的人类可读大小(-h)、按行显示完整信息(-l)。如果你在排查磁盘占用,ls -lah配合文件的大小排序需求,可以再加-S按大小排序,找大文件时不用一个个看。ls -t按修改时间排序也很常用,比如刚部署完项目,想确认哪个文件被刷新了,直接看排序结果就行。

cd的坑多在脚本里。cd到不存在的路径会报错并退出当前 shell 吗?不会,它只是输出一条错误信息,脚本会继续往下跑。我吃过这个亏:部署脚本里cd /opt/app后面直接跟了rm -rf,结果目录不存在时删除操作跑到了当前目录,差点把别的东西清掉。所以脚本里凡是cd到关键路径,我习惯先cd /opt/app || exit 1,这样路径不存在时立刻退出,避免后面的命令在错误的位置执行。

pwd看起来没什么好说,但注意pwd和pwd -P的区别。如果你通过软链接进入一个目录,默认的pwd显示的是逻辑路径(软链接路径),pwd -P显示的是物理真实路径。有些脚本里依赖真实路径做判断,用错了会得到完全不同的结果。比如系统里/var/run通常是指向/run的软链接,你在/var/run下执行不带参数的pwd,显示的是/var/run,但pwd -P会告诉你实际上你在/run。这个细节排查路径相关问题时非常有用。

1.2 cp、mv、rm:操作前多想一秒,删了真找不回来

cp最常用的参数是-r递归复制目录,-p保留属主、时间戳等属性。我备份配置文件时习惯用cp -rp,这样不仅内容一样,权限和时间毫秒级不变,后面对比文件是否真的一致会更精确。复制大文件时加-v能看到进度,虽然不能显示百分比,至少知道任务还在跑。

mv在同一文件系统内是重命名操作,瞬间完成;跨文件系统(比如从/tmp挪到/data)则是先复制再删除,耗时取决于文件大小。这个区别决定了你能否用mv做“秒移动”操作。跨分区移动大文件时,中途如果中断,源文件可能还在但目标只写了一半,这种情况下建议用cp成功后手动确认再删除源文件,比直接mv安全。

rm是 Linux 命令里最需要敬畏的一个。没有回收站,rm -rf下去就是真的没了。我的习惯是:

  • 删除前先用ls确认路径和内容
  • 对关键目录设置别名或写保护,比如给rm加-i提示,或者用safe-rm这类工具保护敏感路径
  • 能不删就不删,改为移动到/tmp/recycle_$(date +%Y%m%d)目录保留几天

如果你已经rm了才发现删错,立刻停止对磁盘的一切写入操作,尝试用extundelete或debugfs恢复,但成功率完全看运气,磁盘一旦被覆盖就无解。修复永远赶不上预防。

1.3 find 与 locate:找文件不是靠肉眼翻目录

find的使用场景很广,但多数人只会find / -name "xxx"。实际工作中我常用的组合:

# 按文件名找 find /data/logs -name "*.log" # 按修改时间找:最近一天内修改过的文件 find /data/app -mtime -1 # 按文件大小找:大于 500MB 的文件,排查磁盘占用利器 find / -size +500M 2>/dev/null # 找到后直接执行操作:把 7 天前的日志删掉 find /data/logs -name "*.log" -mtime +7 -exec rm {} \;

find配合-exec时注意花括号{}和分号\;的写法,很多人第一次用会漏掉转义导致语法错误。现在我也常用find ... -delete直接删除,比-exec rm更简洁,但-delete不能和-exec混用,顺序也有讲究。

locate依赖数据库,速度飞快,但数据库不是实时更新的,新创建的文件可能查不到。执行updatedb后才能刷新。如果文件刚生成几分钟就想找,直接用find更靠谱。我个人的使用原则是:定位系统自带文件用locate,定位业务文件用find。

2. 文本处理三件套:grep、sed、awk 是效率分水岭

2.1 grep:从海量日志里捞关键信息

排查线上问题时,grep是第一个上场的命令。我最常用的几个形态:

# 普通搜索,输出文件名 grep "ERROR" /data/logs/app.log # 递归搜索目录下所有文件 grep -r "exception" /data/app/src/ # 忽略大小写 grep -i "error" app.log # 显示匹配行的前后行,特别适合看日志上下文 grep -B 5 -A 5 "OutOfMemory" app.log # 统计匹配次数 grep -c "timeout" app.log

-B和-A是排查日志的利器,分别显示匹配行的前 N 行和后 N 行。比如日志里出现一条异常,你只看单独一行根本不知道业务走到哪一步了,配合上下文才能还原现场。我习惯固定写成grep -B 5 -A 10,前后各留一点余量。

还要说一个容易忽略的参数:-E启用扩展正则。很多人记不住egrep和grep -E的区别,其实egrep就是grep -E的旧写法,两者等价,现在推荐直接用grep -E。比如从日志里同时匹配多种关键字:

grep -E "ERROR|WARN|FATAL" app.log

grep -o只输出匹配到的部分而不是整行,做字段提取时非常好用。比如从日志里提取所有 IP 地址:

grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" app.log | sort | uniq -c

这条组合后面会讲到,它把“提取 + 去重 + 计数”一次完成,是文本处理常用的流水线思路。

2.2 sed:原地编辑和精准替换

sed被很多人当成“替代 vi 做文本编辑”的工具,其实它的核心能力是流式处理。我最常用的场景有两个:替换和删除。

# 把文件里的 old 全部替换为 new,输出到屏幕(不修改原文件) sed 's/old/new/g' file.txt # 真正修改原文件,修改前自动备份 sed -i.bak 's/old/new/g' file.txt # 删除第 2 行到第 5 行 sed '2,5d' file.txt # 只打印第 10 行到第 20 行 sed -n '10,20p' file.txt

-i参数直接改原文件,这是和grep最大的不同。给-i加后缀(比如-i.bak)会自动生成备份文件,这个习惯我强烈建议保留。有一次我写sed -i 's/127.0.0.1/0.0.0.0/g' config.conf,结果正则写错把配置里的所有1都替换了,如果没有.bak备份就得重装环境。从那以后,凡是涉及批量替换的sed -i,我必定带上备份后缀,确认没问题再手动删备份。

sed的正则默认是基础正则,括号、加号这些特殊字符需要转义。嫌麻烦就直接用-E启用扩展正则,写法更接近直觉,也不用纠结要不要加反斜杠:

# 基础正则写 + 需要转义 sed 's/ab\+c/xxx/g' file.txt # 扩展正则直接写 sed -E 's/abc+/xxx/g' file.txt

2.3 awk:字段切割和统计的瑞士军刀

awk的学习曲线比 grep 和 sed 陡一些,但值得花时间。它的核心模型是按行读入,按分隔符切成字段,然后对字段做处理。默认分隔符是空格,也可以指定。

# 打印每行的第一个和第三个字段 awk '{print $1, $3}' file.txt # 指定冒号作为分隔符,处理 /etc/passwd awk -F: '{print $1, $7}' /etc/passwd # 按条件过滤并统计行数 awk '$1 > 100 {count++} END {print count}' data.txt

实际项目中我最常用awk做日志统计。比如分析访问日志里每个接口的请求次数:

# 假设日志格式是:IP 时间 请求方式 路径 状态码 awk '{print $4}' access.log | sort | uniq -c | sort -rn | head -20

这条组合的价值是把sort、uniq -c、sort -rn三个命令串起来,完成一次从原始数据到排序结果的完整统计。uniq -c会在每行前面加计数,sort -rn按数字倒序排列,head -20取前 20 名。我第一次把这个组合用在生产日志上,十分钟就定位到了一个被频繁刷的异常接口,比肉眼翻日志快太多。

awk还有BEGIN和END块。BEGIN在读取文件前执行,适合设置变量或打印表头;END在读完所有行后执行,适合汇总结果。比如计算一组数字的平均值:

awk '{sum += $1} END {print sum / NR}' numbers.txt

NR是 awk 内置变量,表示已读取的行数。这个写法可以灵活扩展成各种统计需求,把两个字段按条件累加,统计总和、最大值、最小值,都不需要额外写脚本。

3. 系统监控与资源排查:机器卡了别慌,按顺序来

3.1 top、free、df:先看清资源消耗

服务器变卡,第一反应应该是看资源。top是最直观的命令,它会动态刷新 CPU、内存和每个进程的占用情况。进去后我习惯按P键按 CPU 排序,按M键按内存排序。top还可以指定刷新间隔,比如top -d 2两秒刷新一次。

free看内存,重点不是看 free 那一列,而是 available。Linux 会把空闲内存用作缓存,free 显示的是“没被用的”,available 才是“真正可用的”。free -h以人类可读单位输出,不要再看那一串字节数了。

df看磁盘,同样用-h。df -h会列出所有已挂载文件系统的使用情况。如果某个分区使用率到 100%,不只是空间问题,很多程序会在写文件时出错。这时候配合第一章的find / -size +500M找出大文件,清理日志是最直接的解法。

3.2 ps 和 kill:找到占用资源的进程再动手

ps用来看进程快照。ps -ef显示所有进程的完整信息,ps aux的效果类似但字段排列略有不同。实际排查时我常用:

# 找到某个程序的所有进程 ps -ef | grep java # 找到进程并显示 CPU、内存占用,按内存排序 ps aux --sort=-%mem | head -20 # 树状显示进程关系,排查子进程很方便 ps -ef --forest

kill的用法里有个细节:kill -9是最粗暴的方式,直接让内核干掉进程,不给它清理资源的机会。工作中如果遇到正常kill杀不掉的进程,我才会用-9。但有经验的运维一般先给一次温和的TERM(默认信号),等几秒再看进程还在不在,还活着才考虑升级到KILL。因为部分程序(比如数据库)收到TERM会做事务回滚和状态落盘,直接KILL可能损坏数据文件。

3.3 一条命令定位高负载的大致方向

负载高但不知道谁引起的,我习惯按这个顺序排查:

# 先看整体负载和 CPU 队列 uptime # 再看进程占用 top -b -n 1 | head -30 # 结合磁盘 IO 情况 iostat -x 1 3

uptime的一分钟、五分钟、十五分钟平均负载可以判断负载是短期尖峰还是持续走高。如果 1 分钟很高但 15 分钟很低,说明刚刚发生了什么短时任务;如果三个值都高,说明问题持续了一段时间。iostat看磁盘利用率,如果%util接近 100%,大概率磁盘 IO 是瓶颈,这时候就算 CPU 还有余量,整体吞吐也上不去。这个排查思路比盯着top一个命令看更全面。

4. 权限、用户与文件系统:先理解机制再动手

4.1 chmod 和 chown:权限不是越高越好

Linux 权限模型分三组:属主(u)、属组(g)、其他人(o),每组三种权限:读(r=4)、写(w=2)、执行(x=1)。数字表示法就是把三组权限值相加,比如755表示属主可读可写可执行(7),属组和其他人可读可执行(5)。

做开发和部署时最常见的错误是把所有文件都chmod 777。权限全部放开意味着任何用户都能修改,这在多用户服务器上是安全隐患。我的习惯是:

  • 文件用644,目录用755
  • 脚本文件需要执行权限才用755
  • 需要被 Web 服务写入的目录才用775或带组权限的方式
  • 私钥、密码文件用600

chown改属主和属组,chown user:group file可以同时改两者。部署应用时有一个常见坑:用 root 解压的包,普通用户跑起来发现写不了日志,就是因为属主是 root。正确做法是先chown -R appuser:appgroup /data/app,再切换用户启动服务。

4.2 用户和组管理:useradd 之后还有几件小事

创建用户看似就一条命令,但有几个细节经常被忽略:

# 创建用户并指定家目录和 shell useradd -m -d /home/dev -s /bin/bash dev # 设置或修改密码 passwd dev # 把用户加入 sudo 组(不同发行版组名可能不同) usermod -aG sudo dev

-m参数会自动创建家目录,-s指定登录 shell。如果忘了-m,用户登录后会发现没有家目录,shell 会直接落在/,很多配置和密钥都会找不到。usermod -aG中的-a是 append 的意思,追加组而不是替换原有组,少写-a可能把用户原本的附属组全部清掉。

还有一个坑是 sudo 权限。直接改/etc/sudoers文件风险很大,文件语法写错了可能导致所有用户都无法 sudo。正确做法是visudo命令编辑,它会在保存前做语法检查。给用户授权时尽量具体到命令,不要随手给一个ALL=(ALL:ALL) ALL。

4.3 磁盘挂载与空间分析:df、du、mount

df -h看的是整个文件系统的使用情况,du -sh看的是具体目录的大小。排查“根目录快满了”的问题时,顺序是:

# 先看根目录整体使用率 df -h / # 再看根目录下哪个目录最大 du -sh /* 2>/dev/null | sort -rh | head -10

du -sh /*会统计根目录下每个一级目录的大小,sort -rh按人类可读的大小排序,很快就能锁定是/var日志太多还是/home里有大文件。mount用来查看和管理挂载点,比如mount -t ext4 /dev/sdb1 /data手动挂载一块新磁盘,umount /data卸载。卸载时会提示“target is busy”,说明有进程正在使用这个目录,先fuser -m /data找到占用进程再处理,而不是强行卸载。

5. 网络排查命令:连不上不只有 ping 一种解法

5.1 curl 和 telnet:接口通不通一测便知

ping只能证明网络层通不通,真正排查接口问题时,curl才是主力工具。我最常用来验证本地服务是否正常响应:

# 请求并显示响应头和响应体 curl -i http://127.0.0.1:8080/health # 显示详细过程,包括连接、TLS、请求头等信息 curl -v http://127.0.0.1:8080/api/test # 指定请求方式和请求体 curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' http://127.0.0.1:8080/api/create # 带超时控制,避免一直卡住 curl --connect-timeout 5 --max-time 10 http://example.com

curl -v是排查接口问题时的第一选择。它会把 DNS 解析、TCP 连接、TLS 握手、请求头、响应头全都打出来,你能直观看到问题出在哪个环节。有些公司对公网域名访问有限制,如果返回时间特别长或者直接超时,先用curl -v看是 DNS 解析慢还是连接被拒,再决定下一步。排查常见的前后端接口问题基本靠这一条命令就能定位七八成。

telnet现在用得少了,但有一个场景依然高效:只测试某个 TCP 端口是否开放。

telnet 192.168.1.10 3306

能连上说明端口通,连接被拒或被丢弃说明端口不可达或防火墙拦了。不过很多新系统默认没装 telnet 客户端,可以用nc -vz host port替代,效果一样但更轻量。

5.2 ss 和 netstat:端口被谁占了

老运维习惯用netstat,新工具是ss,后者在大并发连接下速度明显更快。查指定端口是谁在监听:

# 查看所有监听端口 ss -lntp # 按端口过滤 ss -lntp | grep 8080 # 老工具 netstat 的等价写法 netstat -lntp | grep 8080

-l只看监听状态,-n用数字显示端口不解析服务名,-t只看 TCP,-p显示占用进程的 PID 和名称。排查“端口被占用启动失败”时,看到 PID 后可以直接ps -ef | grep <pid>确认是哪个程序占的,再决定是 kill 还是换端口。

另一个排查场景是连接数太多。ss -s可以看整体连接统计,ss state established只看已建立的连接。如果某个服务的连接数异常高,配合ss -tn | awk '{print $5}' | sort | uniq -c | sort -rn | head能统计出连接来源的 IP 分布,快速发现扫描或异常请求。

5.3 tcpdump:抓包排查的入门姿势

tcpdump是网络排查的终极工具,但很多人被它复杂的参数吓退。其实入门的常用姿势就这几个:

# 监听指定端口 tcpdump -i any port 8080 # 抓指定来源和目标的包 tcpdump -i eth0 host 192.168.1.20 # 抓包并写到文件,后面用图形工具分析 tcpdump -i any port 443 -w capture.pcap

抓包时最常发现的几个现象是:请求发出后没有响应包(可能被防火墙丢弃)、TCP 重传频繁(网络质量差)、SYN 发出去但没回 SYN-ACK(目标端口不可达或半连接队列满)。tcpdump -w生成的 pcap 文件,可以拉到本地用 Wireshark 慢慢看,比在终端里看刷屏的十六进制舒服得多。

需要注意tcpdump需要 root 权限,而且在生产环境抓包要谨慎,流量大的机器上抓包本身会消耗资源,抓个几秒钟就够了,赶紧Ctrl+C停止,分析文件才是重点。

6. 高频问题与排查技巧实录

6.1 command not found 的原因不只是没安装

遇到“command not found”,第一反应是装包,但有时候包已经装了还是报错。确认一下是不是 PATH 的问题:

# 看命令的真实路径 which java # 看 PATH 是否包含对应目录 echo $PATH

我曾经遇到过一次比较隐蔽的情况:某个工具用源码编译后安装到了/usr/local/bin,但当前用户的 PATH 里没有这个目录,导致每次执行都要写全路径。也就是说,编译安装比包管理器安装更需要关注 PATH 配置。另外还要区分which和whereis,which只查 PATH 范围内的可执行文件,whereis还会找源代码和 man 文档,两者定位问题的角度不同。

6.2 服务器突然卡顿:我惯用的止损顺序

服务器卡到 ssh 都慢,这时候沉住气,按顺序做:

  1. 先uptime,确认负载到底是高还是偶发
  2. 再top -b -n 1,取一次快照,看谁在吃 CPU 或内存
  3. 如果 CPU 不高但负载高,跑iostat -x 1 3看磁盘是否 100% 占用,很可能是日志写入太频繁或死锁导致 IO 卡住
  4. 如果内存被吃满,free -h确认不是单纯的缓存占用,再找具体进程

如果是应用自己把 CPU 吃满,用top拿到 PID 后,可以top -H -p PID看这个进程下哪个线程占得多。如果是 Java 应用,拿到线程 ID 转十六进制,配合jstack就能定位到具体代码行。这个流程走下来,大部分卡顿问题都能定位到原因,处理只是顺带的事。

6.3 日志文件越来越大:别再手动清了

日志增长太快是磁盘满的首要原因,但很多人处理方式是“删掉旧的”,治标不治本。更好的做法是用系统的日志轮转机制,比如logrotate。配置一个按天切割、保留 7 天的规则,日志就不会无限膨胀:

/data/logs/app.log { daily rotate 7 compress missingok notifempty create 0640 appuser appgroup }

这个配置表示每天切割一次,保留 7 个历史文件,切割后压缩,如果日志不存在也不报错,切割后重新创建日志文件并指定属主。配置好之后可以logrotate -d /etc/logrotate.d/app做一次试运行,确认没有问题再放进cron或由系统的定时任务机制触发。

我实际操作中发现,很多团队直到磁盘报警才想起日志管理,临时手动清理既容易误删文件,也容易留下隐患。提前写好轮转配置,让系统自动处理,运维事故能少一大半。

最后再分享两个小习惯

第一个习惯是善用history。命令历史不只是用来上下翻阅的,输入history | grep 关键字可以在历史记录里搜之前执行过的命令。尤其是几天前用过的一条复杂命令,当时没存下来,现在只能靠历史记录找。找到之后我会顺手把它写成一个脚本,下次直接复用。

第二个习惯是命令写进脚本前,先手动验证一遍。很多人写好脚本直接跑,结果因为一个参数位置不对或路径写错,在服务器上留下一堆半成品状态。我调试脚本的习惯是每加一条命令就手动执行一次,确认输出符合预期再进脚本,批量操作的关键步骤前面加echo打印出即将执行的命令,确认无误再去掉echo真正执行。这看起来慢,实际上比出错后排查快得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询