ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux运维命令实战清单:从基础操作到故障排查

Linux运维命令实战清单:从基础操作到故障排查

1. 先把这套命令清单的定位说清楚

1.1 为什么运维命令不能靠死记硬背

我见过太多人收藏了几十篇“Linux命令大全”,真到线上出事的时候还是一条都调不出来。原因不复杂:命令是被场景绑定的,脱离了场景去背参数,就像背了一整本菜谱却从没进过厨房。真正管用的记忆方式,是把每条命令挂到它解决的某个具体问题上,比如“磁盘满了怎么找大头”“服务起不来先看哪一行日志”“端口起了但外面连不上先查什么”。一旦命令和故障现象绑在一起,用两三次就长在脑子里了。

这份汇总的定位是一张可随时查、可顺着练的运维操作地图,不是考试题库。零基础的人照着它能把日常操作跑通,有经验的人可以拿它补自己平时不常用的角落,比如网络排查、日志定位、权限细节这些容易被忽略的部分。文中所有示例都基于常见的 Linux 发行版通用行为,个别发行版差异我会单独点出来。

1.2 命令分三层,别一上来就啃最难的

我一般把运维命令分成三层来学,这个分层对新手特别友好。第一层是生存层:ls cd pwd cat less cp mv rm mkdir touch这些,解决“我在哪、有什么、怎么动”。第二层是诊断层:ps top free df du ss ip grep tail journalctl这些,解决“它为什么不对劲”。第三层是工程层:awk sed find xargs tar systemctl crontab这些,解决“怎么批量、自动化、可重复地干”。

很多人卡住是因为跳过了第二层直接去背第三层,结果awk的语法记得滚瓜烂熟,机器一卡却不知道先敲top还是df。我建议的顺序是:先把第一层练到不用想,再把第二层练到能形成条件反射,最后第三层按需补。这份汇总就按这个逻辑往下铺。

1.3 环境差异与通用性说明

需要提前交代一句:不同发行版在某些命令上确实有差异。ss在较新的系统上是默认,老系统可能只有netstat;systemctl属于 systemd 体系,一些精简容器里根本没有;ip命令取代了老的ifconfig,但很多老脚本还在用后者。文中以现代主流发行版为准,遇到老环境的替代命令我会顺带写上。另外,容器环境里很多命令被裁掉了,排查思路一样,但工具可能要用busybox提供的精简版,这一点在云原生场景下很常见。

提示:本文所有涉及删除、覆盖、改权限的操作,都建议先在测试环境跑一遍,或者先执行只读版本确认影响范围,再加执行动作。

2. 文件与目录:最基础也最容易出事的一层

2.1 ls、cd、pwd 三件套的正确打开方式

pwd看似最没用,实际上在多层sudo或者脚本里,它是你确认“我到底在哪个目录”的唯一可靠手段。别小看这点,我遇到过因为相对路径写错,把备份文件生成到了根目录下的情况,事后靠pwd加ls -l才定位到。

ls的常用参数值得记牢:ls -l看详情,ls -lh让大小变成人类可读,ls -la把隐藏文件也列出来,ls -lt按修改时间倒序,ls -ltr反过来按时间正序。运维里查“最近谁动过什么”,ls -lt是第一反应。ls -i看 inode,排查“文件名删了空间没释放”的时候会用上。

cd的隐藏技巧:cd -回到上一个目录,在两个目录之间来回跳非常省事;cd ~回家目录;cd ..上一级。脚本里我更推荐用绝对路径,因为cd一旦失败,后续所有相对路径操作都会跑偏,这类事故很隐蔽。

2.2 cp、mv、rm 的高危操作与防呆手法

这三条命令的危险程度被严重低估。rm -rf之所以出名,是因为它几乎没有恢复手段。我的习惯是三条:第一,写rm -rf之前先把rm换成ls跑一遍,确认匹配到的文件确实是我想删的;第二,路径尽量用绝对路径,避免在不确定的目录下用通配符;第三,生产环境养成给关键目录做快照或先mv到临时目录、观察几天再删的习惯。

cp的常用参数:cp -r递归复制目录,cp -a保留权限、时间戳、软链接等属性,做备份时强烈推荐-a而不是-r,否则恢复出来的文件权限全乱了。cp -i覆盖前询问,cp -n不覆盖已存在文件,批量部署时用-n能避免误盖配置文件。

mv既是移动也是重命名。它在同一文件系统内是改 inode 指向,几乎瞬间完成;跨文件系统时会变成复制加删除,大文件会很慢,且中途中断可能产生半截文件,这点在迁移数据时要留意。

2.3 find 与 locate:按条件把文件揪出来

find是运维里使用频率最高的命令之一,因为它的条件组合能力太强。基本结构是find 路径 条件 动作。举几个实战里最常用的:

# 按名称查找,忽略大小写 find /var/log -iname "*.log" # 按修改时间查找,7 天以前修改过的 find /data -type f -mtime +7 # 按大小查找,大于 500M 的文件 find / -type f -size +500M # 找到后直接删除(先去掉 -delete 确认结果) find /tmp -type f -name "*.tmp" -mtime +3 -delete # 配合 exec 做批量操作 find /data -type f -name "*.sh" -exec chmod +x {} \;

-mtime +7的含义是修改时间在 7 天以前,注意它按 24 小时取整,不是精确到秒。-size +500M里的M大写是兆字节,小写k是 KB。-exec ... \;会对每个文件单独执行一次,文件多的时候很慢,换成+结尾会批量传参,效率高很多。

locate依赖预先建好的索引数据库,速度极快,但新文件可能查不到,需要先updatedb。日常定位“某个库文件在哪”用它比find快得多,但生产环境索引更新频率不可控,所以我一般在测试机上用它偷懒,线上还是老老实实find。

2.4 权限与属主:chmod、chown、umask 的关系

权限问题是新手最容易懵的地方。ls -l输出里那串-rwxr-xr--要会读:第一位是文件类型(-普通文件、d目录、l软链接),后面三组分别是属主、属组、其他人的权限,每组三位是读r、写w、执行x。

chmod有两种写法。数字写法:读 4、写 2、执行 1,加起来。chmod 755 file就是属主可读写执行、组和其他人可读可执行。符号写法:chmod u+x file给属主加执行权限,chmod g-w file去掉组写权限,chmod o=r file把其他人设成只读。符号写法在微调时更直观,数字写法在批量设置时更省事。

chown改属主和属组:chown user:group file,递归加-R。这里有个坑,chown -R会跟着软链接改目标文件的属主,如果不希望穿透,加-h。

umask决定新建文件的默认权限。默认umask 022时,新建文件是 644、目录是 755。想让自己新建的目录只有自己能进,可以临时umask 077。这个值在脚本里临时设完记得还原,否则后续创建的文件权限会一直不对,这种问题排查起来很费劲,因为文件权限看着“就是不对”,但没人想到是 umask 被改过。

2.5 打包与压缩:tar 的姿势要记熟

tar是运维备份绕不开的命令。记住一组固定搭配就行:打包用tar -czvf 包名.tar.gz 目录,解包用tar -xzvf 包名.tar.gz -C 目标目录。参数含义:c创建、x解压、t查看内容、z走 gzip、v显示过程、f指定文件名(必须放最后)。

查看包内容不用解压:tar -tzvf 包名.tar.gz。只想解出其中某个文件:tar -xzvf 包名.tar.gz 路径/文件名。打包时排除某些目录:tar -czvf backup.tar.gz --exclude=./cache --exclude=*.log ./。

其他格式:.zip用zip -r和unzip,跨平台交互时更通用;.tar.bz2把z换成j;.xz把z换成J。压缩率上 xz 最高但最慢,gzip 最快,日常备份用 gzip 平衡性最好。

3. 文本处理:日志和配置的主要战场

3.1 cat、less、head、tail 的适用边界

cat适合看小文件或拼接文件,大文件直接cat会把终端刷爆。看大文件用less,可以上下翻、/关键词搜索、G跳末尾、gg跳开头、q退出。less +F类似tail -f,但可以随时按Ctrl+C停下来翻历史,这个技巧查滚动日志特别舒服。

head -n 20 file看前 20 行,tail -n 20 file看后 20 行,tail -f file实时跟踪。生产上更常用tail -f加grep:tail -f app.log | grep -i error。注意管道里的grep有时会有缓冲导致输出不及时,加上--line-buffered可以缓解。

tail -n +100 file表示从第 100 行开始往后全部输出,做“跳过前 N 行头部”的处理很好用。head和tail组合可以取中间某段:sed -n '100,200p' file更直接。

3.2 grep:最常用也最容易用错的命令

grep的基本用法大家都熟,真正拉开差距的是几个细节。grep -i忽略大小写,grep -v反向匹配(排除),grep -c只输出条数,grep -n显示行号,grep -r递归目录,grep -l只列出命中的文件名,grep -w全词匹配,grep -E用扩展正则。

几个实战组合:

# 排除掉注释行和空行看配置 grep -vE '^\s*#|^\s*$' /etc/配置文件 # 递归找哪个文件里写了某个配置项 grep -rn "listen_port" /etc/ # 统计日志里某个错误出现多少次 grep -c "Timeout" app.log # 前后各带 3 行上下文,排查报错场景非常好用 grep -n -A 3 -B 3 "Exception" app.log

-A是 after、-B是 before、-C是 context(前后各若干行)。查异常堆栈时用-A 20一把就能把栈打出来,比一行行翻快得多。

一个容易踩的坑:grep默认按行匹配,二进制文件会提示“Binary file matches”,加-a当文本处理。另一个坑是匹配以-开头的字符串,比如查-D参数,要写成grep -- "-D",否则会被当成选项。

3.3 awk:按列处理的结构化利器

awk的定位是“按列取数、按条件过滤、做统计”。默认以空白分隔,$1是第一列,$0是整行,NF是字段数,NR是行号。

最常见的场景是取某列:

# 取出访问日志里的 IP 列 awk '{print $1}' access.log # 指定分隔符为冒号,取第一列和第三列 awk -F: '{print $1, $3}' /etc/passwd # 过滤第三列大于 100 的行 awk '$3 > 100 {print $0}' data.txt # 按第一列聚合求和 awk '{sum[$1] += $3} END {for (k in sum) print k, sum[k]}' data.txt

最后那条聚合写法是运维统计的常用套路:先按某列做哈希累加,最后在END里输出。比如统计每个接口的调用次数、每个 IP 的请求量,都用这个模板。需要注意的是awk的数组是无序的,输出顺序不固定,要排序就接| sort -k2 -nr。

awk还能做格式化输出,printf比print更可控:awk '{printf "%-20s %10d\n", $1, $2}'。日志分析要出报表的时候比print好看得多。

3.4 sed:不用打开文件就能改内容

sed的核心是“流编辑”,最常用的是替换:sed 's/旧/新/g' file。不加-i只输出到屏幕,加了-i才真正写回文件。我强烈建议先不加-i看一遍输出对不对,确认无误再加。-i改动是不可逆的,加个备份后缀更稳:sed -i.bak 's/旧/新/g' file。

按行操作:sed -n '10,20p' file打印 10 到 20 行;sed '5d' file删第 5 行;sed '/关键词/d' file删匹配行;sed '1i\新内容' file在第一行前插入。指定行替换:sed '3s/旧/新/'只改第 3 行。

sed的正则默认是基础正则,要用-E才支持扩展写法。替换内容里出现/时会冲突,可以把分隔符换成别的字符:sed 's#/old/path#/new/path#g',这个技巧在处理文件路径时特别顺手。

3.5 sort、uniq、wc、cut:统计流水线的四个零件

这几条命令单看都很简单,组合起来才是威力所在。sort排序,-n按数值、-r倒序、-k2按第二列、-u去重、-t指定分隔符。uniq去重,但必须先排序,因为它只处理相邻重复行,-c统计次数。wc -l数行数,-c数字节。cut -d指定分隔符、-f指定列。

一个典型的分析流水线:

# 统计访问量前 10 的 IP awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10

这条命令几乎是日志分析的标准起手式。拆开看:取第一列、排序让相同 IP 相邻、uniq -c计数、按次数倒序、取前十。每一步都只做一件事,串起来就是完整分析。类似的还有统计状态码分布、统计接口耗时区间,套同一个骨架换一下取值列就行。

4. 系统状态:出问题先看哪几个指标

4.1 CPU 与负载:top、uptime、vmstat

机器卡了,第一反应是top。看几个关键位置:顶部load average是 1、5、15 分钟的平均负载,跟核数对比着看,单核机器负载 4 就已经很吃力,八核机器负载 4 还算轻松。%Cpu(s)那一行重点看wa,也就是 IO 等待,这个值高说明瓶颈在磁盘不在 CPU。进程列表里按P按 CPU 排序、按M按内存排序、按1展开每个核的占用。

uptime一条命令给出运行时长和负载,登录机器先敲它,能快速判断是长期高负载还是刚起来。vmstat 1 5每秒采样一次共五次,重点看r运行队列(大于核数说明在排队)、b阻塞进程、si和so换页(非零说明内存吃紧)、waIO 等待。

这些工具的输出要建立“基线”意识,也就是你平时正常时是多少。没有基线,看到wa是 5% 你也不知道是好是坏。我的习惯是给每类机器记一个粗略正常区间,出问题时对着比,快得多。

4.2 内存:free 与 /proc/meminfo

free -h是最直观的。重点看available而不是free,因为 Linux 会把空闲内存拿去做缓存,free很小很正常,available才是应用真正还能用的量。buff/cache高不是问题,反而说明缓存用得好。

swap那一行要警惕。used持续增长说明物理内存不够,系统在换页,性能会明显掉。这时候vmstat的si/so也会有反映。要看更细的指标去/proc/meminfo,里面MemAvailable、Dirty(待写回磁盘的数据量)、Slab(内核对象占用)都值得关注。

一个常见误区:看到free很低就急着清缓存。清缓存只能短暂缓解,不解决根本问题,而且会拖慢后续读性能。真正该做的是找谁占用了内存,ps aux --sort=-%mem | head一眼就能看到大户。

4.3 磁盘:df、du、iostat 三件套

磁盘问题分两种:空间满和 IO 慢,排查手段不一样。

空间满先df -h找哪个挂载点满了,再进那个目录用du -sh * | sort -rh | head找大目录,逐层往下钻。du -sh统计当前层每个子项大小,sort -rh按人类可读的大小倒序,这个组合定位大文件非常快。

有个经典陷阱:df显示满,du加起来却对不上。原因通常是文件被删了但进程还开着句柄,空间没释放。用lsof | grep deleted找出来,重启对应进程或者清掉句柄就恢复了。

IO 慢用iostat -x 1,重点看%util(接近 100% 说明磁盘饱和)和await(平均等待时间,明显偏高说明队列积压)。iotop能直接看到是哪个进程在读写,需要额外安装。排查 IO 问题时这两个配合用,定位速度会快很多。

4.4 网络:ss、ip、ping、curl

ss是查看连接状态的主力,比netstat快。ss -tlnp看监听的 TCP 端口和对应进程,这是“服务到底起没起”的第一验证命令。ss -s看汇总统计,ss -tn state established看已建立的连接。

ip addr看网卡和 IP,ip route看路由表,ip link看链路状态。ifconfig是老命令,很多新系统默认没装,知道替代关系就行。

ping测连通性,-c 4发四个包。traceroute看路径,中间某跳不通不一定代表目标不通,有些节点默认不回。curl是验证服务可用性的利器:curl -I只看响应头,curl -v看完整过程,curl -o /dev/null -s -w "%{http_code} %{time_total}\n"输出状态码和耗时,做健康检查脚本时这个写法很常用。

端口起了但连不上,排查顺序我一般是:ss -tlnp确认监听地址是不是0.0.0.0而不是127.0.0.1,然后看本机防火墙规则,再看对端能不能telnet或curl通,最后看云环境的网络策略。这个顺序能把大部分“端口不通”的问题一次定位。

4.5 进程管理:ps、pstree、kill、nohup

ps aux看全量进程,ps -ef是另一种风格,两者都能用。ps aux --sort=-%cpu | head找 CPU 大户,--sort=-%mem找内存大户。ps -ef | grep 关键词找特定进程,注意这条命令本身也会出现在结果里,加| grep -v grep排除掉。

pstree -p用树形结构看父子关系,排查“某个进程反复重启”时特别有用,能看清是谁在拉它。kill -9是强杀,但更推荐先kill -15让进程自己收尾,很多服务需要时间落盘和释放资源,直接-9可能丢数据。pkill -f 关键词按命令行匹配杀进程,killall 进程名按名字杀。

长期运行的任务用nohup 命令 &挂到后台,输出默认进nohup.out。更规范的做法是用systemd托管,或者用screen、tmux这类会话工具,断开连接后还能回来接着看。nohup的坑在于它不处理标准输入,交互式脚本挂上去可能卡住。

5. 用户、服务与定时任务

5.1 用户与组:useradd、usermod、passwd

新建用户useradd -m -s /bin/bash 用户名,-m建家目录、-s指定 shell。设密码passwd 用户名。改属性用usermod,比如把用户加进附加组:usermod -aG 组名 用户名,-a一定要加,否则会把用户从其他附加组里踢出去,这个坑很常见。

查用户信息id 用户名,看所属所有组。删用户userdel -r 用户名,-r一并删家目录,不加-r会留下孤立的目录和文件。组管理groupadd、groupdel、gpasswd -a 用户 组。

用户相关的配置文件要认识:/etc/passwd存基本信息,/etc/shadow存密码哈希(只有 root 可读),/etc/group存组信息。改这些文件一定要用专门命令,手动编辑容易格式错乱导致登录不了。

5.2 sudo 与权限边界

生产环境不建议直接用 root 登录,走sudo更可控。sudo -l看当前用户能执行哪些命令,sudo -u 用户名 命令以指定用户身份执行,sudo -i切到 root 的登录环境。

/etc/sudoers的编辑必须用visudo,它会在保存时做语法检查,直接编辑出错可能导致所有人都用不了 sudo。常见配置是给某个组免密执行特定命令,粒度控制到命令级别比直接给全量权限安全得多。

5.3 systemd 服务管理:systemctl 与 journalctl

现代发行版基本都用 systemd。常用命令一览:systemctl start/stop/restart 服务名、systemctl status 服务名看状态、systemctl enable/disable 服务名控制开机自启、systemctl reload 服务名重载配置(不中断服务)、systemctl list-units --type=service列出所有服务。

status的输出信息量很大,能看到最近几条日志、主进程 PID、启动时间、退出码。服务起不来时先看这个,多数情况错误原因就在里面。

日志用journalctl。journalctl -u 服务名看某个服务的日志,-f实时跟踪,-n 100最近 100 行,--since "10 min ago"按时间过滤,-p err只看错误级别。这几个参数组合起来,定位服务异常基本够用。

systemctl daemon-reload是改完 unit 文件后必须执行的一步,很多人改完配置发现不生效,就是漏了这条。

5.4 crontab:定时任务的写法与坑

crontab -e编辑当前用户的定时任务,crontab -l列出,crontab -r全部删除(这条慎用,没有确认提示)。

格式是五个时间字段加命令:分、时、日、月、周。0 3 * * *表示每天凌晨 3 点。*/5 * * * *每 5 分钟。0 9-18 * * 1-5工作日 9 点到 18 点整点。这些写法要练熟。

几个高频坑:第一,crontab的环境变量和你登录 shell 的不一样,脚本里最好写绝对路径,或者在任务开头显式加载环境。第二,命令里的%有特殊含义,要做日期格式化得转义成\%。第三,标准输出和错误输出默认会发邮件,机器没配邮件就会堆积,建议重定向到日志文件:>> /var/log/任务.log 2>&1。第四,任务执行时间重叠时可能并发跑,加个锁文件或用flock控制。

6. 日志排查与故障定位实战

6.1 日志都在哪,先有个地图

系统日志集中在/var/log。messages或syslog是系统级日志,secure或auth.log是登录认证日志,cron是定时任务日志,dmesg或kern.log是内核日志。应用日志一般在自己目录下,nginx 在/var/log/nginx/,数据库各有各的位置。

用 systemd 的服务日志统一走journalctl,位置在/run/log/journal或/var/log/journal,重启后是否保留取决于配置。

dmesg -T看内核日志并转成可读时间,排查硬件、OOM、磁盘报错必看。OOM 杀进程会在dmesg里留下明显记录,应用莫名其妙消失时先查这里。

6.2 三个高频故障场景的命令组合

场景一:服务起不来。顺序是systemctl status 服务名看状态和最近日志,journalctl -u 服务名 -n 100 --no-pager拉详细日志,如果是配置文件问题,再用服务程序 -t做配置语法检查(很多服务支持这个参数)。端口冲突的话ss -tlnp | grep 端口看谁占着。

场景二:磁盘突然满了。df -h定位挂载点,du -sh /* | sort -rh | head逐层钻,lsof | grep deleted查已删未释放的句柄,find / -type f -size +1G找大文件。四步下来基本能锁定。

场景三:接口变慢。top看 CPU 和负载,vmstat 1看 IO 等待,ss -s看连接数是否异常增长,iostat -x 1确认磁盘,然后去应用日志里grep慢请求关键字。如果连接数暴涨但 CPU 不高,多半是连接没释放或者下游卡住,往这个方向查。

6.3 排查的基本原则:先看现象再动手

我踩过最深的坑是“一上来就改配置”。正确的顺序是先收集现象:什么时候开始的、影响范围多大、有没有相关变更、日志里第一条异常是什么。把这些理清楚再动手,能避免大量无效操作。改之前一定要备份原文件,改完立即验证,验证不通过立刻回滚。这个流程听着笨,但救过我很多次。

7. 常见问题速查与个人避坑经验

7.1 高频问题对照表

现象优先排查命令常见原因
磁盘显示满但 du 对不上lsof | grep deleted文件被删但进程仍持有句柄
端口监听正常但外部连不上ss -tlnp、ip addr监听在 127.0.0.1 或网络策略限制
服务反复重启pstree -p、journalctl -u被守护进程拉起且内部报错退出
内存看着快没了free -h、ps aux --sort=-%mem缓存占用属正常,需看 available
定时任务不执行crontab -l、/var/log/cron环境变量缺失或路径写错
命令找不到which、echo $PATHPATH 未包含或包未安装
权限拒绝但权限看着对ls -lZ、getenforce安全模块策略拦截
日志不更新ls -l /proc/PID/fd日志被轮转但进程仍写旧 inode

7.2 我个人的几条经验

第一,命令要形成“肌肉记忆”的唯一办法是真用。我当时是给自己搭了一台测试机,把每天学到的东西写成小脚本跑一遍,出问题自己修。比看十篇文章管用。

第二,凡是带-r、-f、-i、-9的参数,敲之前停一秒想清楚影响范围。这一秒能省掉后面几个小时的恢复工作。

第三,善用history和Ctrl+R。history | grep 关键词找以前执行过的命令,Ctrl+R反向搜索历史。复杂命令跑通之后,可以考虑在.bashrc里设alias,但别把危险命令设成短别名,容易误触。

第四,所有改动先备份。配置文件加个.bak后缀,脚本改动先复制一份,数据库操作前先导出。这个习惯看着土,但它是最有效的兜底。

第五,学会看手册。man 命令是最权威的,命令 --help是最快的。网上文章可能过时或者有错,手册不会。刚开始看man会觉得晦涩,看多了就习惯了,而且能发现很多别人文章里没提的参数。

最后分享一个我常用的组合,查某个时间段内某个关键词的日志并统计分布:

journalctl --since "2024-01-01 00:00" --until "2024-01-01 12:00" \ | grep -i "error" \ | awk '{print $5}' \ | sort | uniq -c | sort -nr | head

这条命令能快速告诉你错误集中在哪个来源,比一行行翻日志效率高太多。命令本身不复杂,关键是知道什么时候该把哪几条串起来,这个判断力只能靠一次次真实排查积累出来。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进