1. 从零搭建一套顺手的服务器命令知识库
很多人第一次接触服务器,脑子里蹦出来的第一个念头就是“命令太多记不住”。我刚开始那会儿也一样,ls、cd、top、df这些还能应付,一旦遇到日志排查、进程卡死、磁盘爆满,整个人就懵了。后来我发现,真正的问题不在于命令数量多,而在于没有把它们按“场景”串起来。你不需要背下几百条命令,你只需要在遇到具体问题时,知道该敲哪一条、参数怎么给、输出怎么看。
这篇内容就是围绕这个思路展开的。我会把服务器日常运维中最常打交道的命令,按照实际使用场景重新组织一遍,不是那种从 A 到 Z 的字典式罗列,而是“遇到什么问题,用什么命令,怎么解读结果”。适合刚上手 Linux 服务器的朋友,也适合已经用了几年但总觉得知识零散、想系统梳理一遍的同行。核心关键词就一个:服务器命令,但我会把它拆成文件操作、进程管理、网络排查、磁盘与性能、日志分析、权限与用户这几大块,每一块都配上我实际踩过的坑和验证过的参数组合。
先说一个我自己的教训。早年有一次线上服务响应变慢,我第一反应是重启,结果重启完十分钟又卡了。后来才学会先用top看负载,再用iostat看磁盘 IO,最后定位到是一个日志文件把磁盘写满了。如果当时手边有一套按场景整理的命令清单,可能五分钟就解决了。所以下面这些内容,你可以直接当成自己的“服务器命令速查手册”来用,也可以在此基础上继续扩充。
2. 文件与目录操作:别只会 ls 和 cd
2.1 查看文件内容时,cat、less、tail 到底怎么选
很多人一上来就用cat,文件小的时候没问题,一旦遇到几百兆的日志文件,终端直接卡死,只能强制关掉重开。我的习惯是:小于 100 行的配置文件用cat,大文件一律用less,实时日志用tail -f。
less的好处是可以上下翻页、搜索关键字,按/输入关键词回车就能定位。退出按q。如果你只想看文件末尾的几十行,tail -n 50 filename比cat高效得多。实时跟踪日志用tail -f filename,但要注意,如果日志滚动特别快,终端会刷屏,这时候可以配合grep过滤,比如tail -f app.log | grep ERROR。
还有一个容易被忽略的命令是head,默认看前 10 行,适合快速确认文件格式。比如拿到一个 CSV 文件,先head -n 3 data.csv看看列名和分隔符,再决定怎么处理。
提示:
cat还有一个常见用法是合并文件,cat file1 file2 > file3,但要注意>会覆盖目标文件,如果 file3 已存在且重要,先用>>追加或者提前备份。
2.2 查找文件:find 和 locate 的取舍
find是服务器上最强大的查找工具,但参数多、速度慢。locate基于预建索引,速度快但可能不是最新结果。我的经验是:临时找文件用find,日常高频查找用locate但记得定期updatedb。
find最常用的几个场景:
- 按文件名查找:
find /var/log -name "*.log" - 按修改时间查找:
find /tmp -mtime +7(7 天前修改的) - 按大小查找:
find / -size +100M(大于 100M 的文件) - 查找后执行操作:
find /tmp -name "*.tmp" -exec rm {} \;
这里有个坑:find /会遍历整个文件系统,包括/proc、/sys这些虚拟目录,速度极慢还可能报错。建议限定目录范围,或者用-xdev参数避免跨文件系统。
locate的用法很简单:locate nginx.conf,但它依赖/var/lib/mlocate/mlocate.db这个数据库,新创建的文件可能搜不到。手动更新用updatedb,但注意这会消耗一定 IO,别在业务高峰期跑。
2.3 文件权限与属主:chmod 数字法的快速心算
chmod有两种写法:符号法和数字法。符号法适合微调,比如chmod u+x script.sh给属主加执行权限。数字法适合一次性设定,比如chmod 755 script.sh。
数字法的规则是:读(r)=4,写(w)=2,执行(x)=1,三组权限分别对应属主、属组、其他用户。所以 755 就是属主 4+2+1=7,属组 4+1=5,其他 4+1=5。常用的组合有:
| 数字 | 含义 | 典型场景 |
|---|---|---|
| 644 | 属主读写,其他只读 | 普通文件、配置文件 |
| 755 | 属主读写执行,其他读执行 | 脚本、目录 |
| 600 | 只有属主读写 | 私钥、敏感配置 |
| 700 | 只有属主读写执行 | 私有目录 |
改属主用chown user:group filename,递归改目录用-R。但-R要小心,别把系统目录的属主改乱了。我一般会先ls -l确认当前权限,改完再ls -l复核一遍。
3. 进程与资源管理:top 之外的进阶工具
3.1 用 top 和 htop 快速定位高负载进程
top是服务器上最常用的实时监控工具,默认按 CPU 使用率排序。进入界面后,按M按内存排序,按P按 CPU 排序,按1展开每个 CPU 核心的详情。退出按q。
但top的交互体验一般,如果服务器上装了htop,我更推荐用它。htop有彩色界面、支持鼠标点击、可以直接杀进程,还能横向滚动看完整命令。安装命令因系统而异,Debian/Ubuntu 系用apt install htop,RHEL/CentOS 系用yum install htop。
看top输出时,重点看三行:第一行的load average,第二行的Tasks,第三行的%Cpu(s)。load average的三个数值分别是 1 分钟、5 分钟、15 分钟的平均负载。如果 1 分钟值远高于 15 分钟值,说明负载在突增;如果三个值都高,说明系统持续繁忙。一般来说,负载值不应超过 CPU 核心数,超过就说明有进程在排队。
3.2 ps 与 pgrep:精准找到目标进程
ps aux是最常用的进程查看命令,输出所有用户的进程。但输出太长,通常配合grep使用:ps aux | grep nginx。这里有个小坑:grep本身也会出现在结果里,可以用grep -v grep过滤掉。
更优雅的方式是用pgrep:pgrep -a nginx直接列出进程名匹配的进程和完整命令。pgrep -u root列出 root 用户的进程。如果要看进程树,用pstree -p,能直观看到父子进程关系。
杀进程用kill,默认发 TERM 信号(15),让进程自己清理退出。如果进程无响应,用kill -9发 KILL 信号强制终止。但-9是最后手段,因为进程来不及保存状态,可能导致数据不一致。我一般先kill,等几秒,不行再kill -9。
3.3 后台任务与 nohup:让命令在断开后继续跑
SSH 会话断开后,前台运行的命令会被终止。如果想让一个耗时任务继续跑,有两种方式:nohup和screen/tmux。
nohup的用法:nohup long_running_command > output.log 2>&1 &。这里> output.log把标准输出重定向到文件,2>&1把标准错误也重定向到同一文件,最后的&让命令在后台运行。执行后会返回一个进程号,可以用jobs -l查看后台任务,用fg %1调回前台。
但nohup的缺点是任务管理不方便,看不到实时输出。所以我更推荐tmux:tmux new -s mysession创建一个会话,在里面跑命令,按Ctrl+B然后D分离会话。下次 SSH 进来用tmux attach -t mysession重新连接,输出还在。screen类似,但tmux的分屏和复制模式更好用。
4. 网络排查:从 ping 到 tcpdump 的完整链路
4.1 连通性检查:ping、telnet、curl 的分工
ping是最基础的连通性测试,ping -c 4 example.com发 4 个包就停。但很多服务器禁 ping,所以 ping 不通不代表服务不可用。
telnet用来测端口:telnet 192.168.1.1 80,如果显示Connected说明端口开放。但telnet默认没装,可以用nc -zv 192.168.1.1 80替代,-z表示只扫描不发送数据,-v显示详细信息。
curl更强大,能直接发 HTTP 请求:curl -I http://example.com只看响应头,curl -v显示完整请求过程。排查接口问题时,我常用curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' http://api.example.com/endpoint来模拟请求。
4.2 端口与连接状态:netstat 和 ss 的对比
netstat -tulnp是经典命令,显示所有监听端口和对应进程。但netstat在新版 Linux 上逐渐被ss取代,因为ss更快、输出更清晰。
ss -tulnp参数含义:-tTCP,-uUDP,-l监听状态,-n显示端口号而非服务名,-p显示进程。输出里Local Address是监听地址,Peer Address是连接过来的地址。
如果要看某个端口的连接数:ss -tn state established '( sport = :80 )' | wc -l。这个命令统计 80 端口已建立的连接数,对判断并发量很有用。
4.3 抓包分析:tcpdump 的常用过滤表达式
tcpdump是网络排查的终极武器,但输出量大,必须配合过滤条件。基本用法:tcpdump -i eth0 -nn port 80,-i指定网卡,-nn不解析域名和端口名,port 80只抓 80 端口。
更精细的过滤:
- 抓特定 IP:
tcpdump -i eth0 host 192.168.1.100 - 抓特定网段:
tcpdump -i eth0 net 192.168.1.0/24 - 抓 TCP 标志位:
tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0' - 保存到文件用 Wireshark 分析:
tcpdump -i eth0 -w capture.pcap
抓包时要注意权限,普通用户可能没权限,需要sudo。另外抓包会消耗 CPU 和磁盘,别长时间跑,抓完及时Ctrl+C停止。
5. 磁盘与性能:df、du、iostat 的组合拳
5.1 磁盘空间排查:df 和 du 的配合
df -h查看各分区使用率,-h以人类可读格式显示(GB、MB)。如果某个分区使用率超过 90%,就要警惕了。
但df只显示分区级别,具体哪个目录占空间要用du。du -sh /var/log查看 /var/log 总大小,du -h --max-depth=1 /var查看 /var 下每个子目录的大小。这里有个坑:du统计的是文件占用的块数,可能和df的结果有差异,因为被删除但仍在被进程占用的文件不会出现在du里。
遇到df显示满但du找不到大文件的情况,用lsof | grep deleted查找被删除但未释放的文件。重启对应进程就能释放空间。
5.2 磁盘 IO 性能:iostat 的关键指标
iostat -x 1每秒刷新一次,显示每个磁盘的详细 IO 统计。重点看几个指标:
%util:磁盘繁忙程度,接近 100% 说明磁盘是瓶颈await:平均等待时间(毫秒),包括排队时间svctm:平均服务时间,反映磁盘本身性能r/s和w/s:每秒读写次数
如果%util高但await不高,说明 IO 量大但磁盘处理得快;如果await远大于svctm,说明排队严重,可能需要升级磁盘或优化 IO 模式。
5.3 内存与交换分区:free 和 vmstat
free -h查看内存使用,重点看available列,这是真正可用的内存。buff/cache是系统缓存,虽然算在 used 里,但可被回收,不用太担心。
vmstat 1每秒输出一行,关注si和so两列,分别是交换分区换入和换出。如果这两个值持续大于 0,说明物理内存不足,系统在频繁使用交换分区,性能会明显下降。
6. 日志分析:grep、awk、sed 的三剑客用法
6.1 grep 的高频参数与正则技巧
grep是日志分析的第一把刀。常用参数:
-i忽略大小写-r递归搜索目录-n显示行号-C 3显示匹配行前后各 3 行-v反向匹配,排除某些行
正则方面,grep -E支持扩展正则,比如grep -E "error|fail" app.log匹配 error 或 fail。如果要统计匹配行数,用grep -c。
我排查问题时经常用grep -n -C 5 "Exception" app.log,这样能看到异常前后的上下文,快速定位问题原因。
6.2 awk 按列提取与统计
awk适合处理结构化文本。比如日志格式是时间 IP 状态码 耗时,用空格分隔,那么:
- 提取第 2 列:
awk '{print $2}' access.log - 统计状态码分布:
awk '{print $3}' access.log | sort | uniq -c | sort -rn - 计算平均耗时:
awk '{sum+=$4} END {print sum/NR}' access.log
awk的内置变量很实用:NR是当前行号,NF是当前行的字段数,$0是整行内容。
6.3 sed 批量替换与行操作
sed主要用于替换和删除行。替换:sed 's/old/new/g' file.txt,g表示全局替换。直接修改文件用-i:sed -i 's/old/new/g' file.txt。
删除空行:sed '/^$/d' file.txt。删除包含某关键词的行:sed '/debug/d' app.log。打印特定行:sed -n '10,20p' file.txt打印第 10 到 20 行。
sed和awk经常配合使用,比如先grep过滤,再awk提取,最后sed替换格式,形成一条完整的处理链路。
7. 权限与用户管理:useradd、sudo、ssh 密钥
7.1 用户与用户组的基本操作
创建用户:useradd -m -s /bin/bash username,-m创建家目录,-s指定 shell。设置密码:passwd username。删除用户:userdel -r username,-r同时删除家目录。
创建用户组:groupadd devgroup。把用户加入组:usermod -aG devgroup username,-a表示追加,不加-a会覆盖原有组。查看用户所属组:groups username。
7.2 sudo 权限的精细控制
直接给用户 root 权限不安全,更好的方式是用sudo。编辑/etc/sudoers用visudo命令,它会检查语法错误。添加一行:username ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx,这样用户只能免密重启 nginx,不能执行其他 root 命令。
如果想让用户执行所有命令但需要输密码:username ALL=(ALL) ALL。但生产环境建议按需授权,最小权限原则。
7.3 SSH 密钥登录与安全加固
密码登录容易被暴力破解,推荐用密钥登录。本地生成密钥对:ssh-keygen -t rsa -b 4096,一路回车。然后把公钥传到服务器:ssh-copy-id user@server。
服务器端确认~/.ssh/authorized_keys文件权限是 600,.ssh目录权限是 700。然后编辑/etc/ssh/sshd_config,设置PasswordAuthentication no禁用密码登录,PermitRootLogin no禁止 root 直接登录。改完重启 sshd 服务。
注意:改 SSH 配置前,先确保密钥登录已经成功,否则可能把自己锁在外面。我一般会开两个终端,一个改配置,一个保持连接测试。
8. 我的常用命令组合与踩坑记录
8.1 几条我每天都在用的组合命令
- 查看当前目录下最大的 10 个文件:
du -ah . | sort -rh | head -n 10 - 实时监控某进程的 CPU 和内存:
top -p $(pgrep -d',' process_name) - 统计 Nginx 访问日志中 IP 的访问次数:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -n 20 - 查找并删除 7 天前的日志:
find /var/log -name "*.log" -mtime +7 -delete - 查看某端口被哪个进程占用:
ss -tulnp | grep :8080
这些命令我用了好几年,基本覆盖了日常 80% 的排查场景。你可以把它们记在便签上,或者写进自己的 shell 别名里。
8.2 那些年我踩过的坑
第一个坑:rm -rf后面跟变量。有一次脚本里写rm -rf $DIR/*,结果$DIR为空,变成了rm -rf /*,幸好当时权限不够,只删了当前目录。教训是:删除前先echo确认路径,或者用set -u让未定义变量报错。
第二个坑:chmod -R 777图省事。结果把私钥文件也设成了所有人可读,安全审计直接报警。后来我学会了按需授权,私钥一律 600,目录 755,脚本 755。
第三个坑:kill -9杀数据库进程。有一次 MySQL 卡住,我直接kill -9,结果数据文件损坏,花了半天恢复。后来知道数据库要用mysqladmin shutdown或者systemctl stop优雅停止。
第四个坑:df和du结果不一致。排查了半天才发现是日志文件被删除但进程还在写,lsof | grep deleted找到后重启进程才释放空间。
8.3 如何持续积累自己的命令库
我的做法是建一个 Markdown 文件,按场景分类,每遇到一个新问题就记一条。比如“磁盘满”下面记df -h、du -sh、lsof | grep deleted;“端口占用”下面记ss -tulnp、lsof -i:端口。时间长了,这个文件就是自己的知识库。
另外,善用man和--help。man command看完整手册,command --help看快速帮助。遇到不熟悉的参数,先查再试,别凭感觉敲。
最后分享一个小技巧:用history查看历史命令,history | grep keyword快速找到之前用过的命令。Ctrl+R反向搜索历史命令,输入关键词就能调出最近一条匹配的命令,效率极高。
服务器命令这东西,说到底就是“用进废退”。你不需要一次记住所有,但要在遇到问题时知道去哪查、怎么试。上面这些内容是我自己从无数次踩坑中总结出来的,希望能帮你少走点弯路。如果你也有自己的常用命令组合,不妨也整理一份,时间长了你会发现,这比任何速查表都管用。