Linux运维实战:从文本处理到进程网络排查的核心命令
很多朋友学Linux基础指令最容易犯的一个毛病就是“背命令”。今天记住了ls -l明天遇到ps aux又懵了总感觉Linux命令像一本翻不完的字典越学越没底。所以这个系列我坚持用“场景带动命令”的方式来讲。第一篇我们基本搞定了文件与目录操作也就是说你已经能在一台Linux机器上“走”得开了。这篇“【2】”咱们重点解决另一件事怎么让Linux听你的话帮你处理文本、管理用户、看护进程、搞定网络和磁盘。这些都是日常运维和开发里躲不开的硬骨头也是面试和实际工作中最爱被反复问到的点。这篇内容适合两类人一类是刚把入门命令过完一遍、急着想上手干活的初学者另一类是会用一些命令、但遇到具体故障时比如磁盘满了、端口被占、进程杀不掉不知道怎么下手的新手运维。这里没有花哨的炫技都是我从实际机器上一次次试出来的、最朴素好用的东西每一条都能直接抄到你的终端里跑。1. 文本处理三件套grep、sed、awk1.1 grep日志排查的第一把手很多人在Windows下习惯了“CtrlF”到了Linux最不适应的就是“我都不知道日志里发生了什么”。这时候grep就是你的救星。grep本身的意思很简单在文件里找匹配的行。我常用的几个姿势grep -i error /var/log/syslog # 忽略大小写 grep -n timeout app.log # 显示行号方便回头定位 grep -v ^# nginx.conf # 排除注释行看有效配置 grep -E ERROR|WARN app.log # 同时匹配多个关键词 grep -c exception app.log # 只数数量不打印细节这里重点说-E。很多老教程会让你用egrep但新版系统里egrep已经改为“警告并建议改用grep -E”所以趁早养成用grep -E的好习惯。-E表示启用扩展正则比如管道符|、括号()这些都不需要再转义。一个真实场景网站访问量突然上去了你想知道五分钟内有多少次5xx错误。grep 10/May/2025:14:0[0-5] /var/log/nginx/access.log | grep -E 50[0-9] | wc -l一句话就把时间窗口和状态码都圈住了这就是组合命令的威力。grep是流水线里最常用的第一道筛子几乎可以配合一切命令使用。1.2 sed批量改文件的老中医sed是个流编辑器。什么叫“流”你可以想象成一条流水线文件内容像水流一样经过sedsed对每一行做一次手术再放出来。最经典的用法是替换sed -i s/oldtext/newtext/g config.ini注意这个-i它表示“直接修改原文件”。新手最怕的就是这个参数一旦写错老配置就没了。所以我个人的习惯是先不加-i跑一遍看输出确认无误再加-i执行同时给原文件留个备份。cp config.ini config.ini.bak sed -i s/192.168.1.100/192.168.1.200/g config.ini如果遇到批量替换某个目录下所有文件里的IP可以配合find使用find ./config -type f -name *.conf -exec sed -i s/10.0.0.1/10.0.0.2/g {} \;这里我再提一个容易忽略的场景删除配置文件里的注释行和空行让核心逻辑清晰可见。查看或者交接环境时特别好用。sed -i /^#/d; /^$/d nginx.conf/^#/d表示删除以#开头的行/^$/d删除空行两个操作用分号串在一起一次搞定。但同样提醒一句有的配置文件里“行内注释”是在配置项后面的比如worker_processes 4; # CPU核数这种就不能直接用^#删你得用sed -i s/#.*$//先把行尾注释去掉。1.3 awk按列拆数据的瑞士军刀如果grep是按行捞那awk就是按列切。它是个编程语言但我们入门只需要掌握它的“字段拆分”思维。默认情况下awk用空格或Tab把一行拆成多个字段$0代表整行$1是第一个字段$2是第二个以此类推。举一个非常常见的例子想找出系统里CPU占用最高的进程PID一般会被推荐用top但top是动态界面不适合脚本。用ps加awk才是正解ps aux | awk $3 80 {print $2, $11, $3%}这段的意义是只要CPU列第三列超过80就把PID、命令名和CPU占用打印出来。再比如df输出磁盘使用率它默认带表头而且可能跨行换行新手看得很乱。用awk处理一次df -h | awk NR1 || $5 80 {print $6, $5}NR1表示保留第一行表头$5是使用率百分比那一列超过80的挂载点就报警。awk还能在输出里自己拼字符串。我经常这样给运维群发告警df -h | awk NR1 || $5 80 {print 告警: $6 使用率 $5}这个双引号拼接字符串的思路很简单但你一旦用上就会发现文本处理的能力边界被直接拓宽了。1.4 管道思维把工具串成流水线前面三个工具单独用都只是“命令”真正形成战斗力的是管道符|它能把前一个命令的输出当成后一个命令的输入。这就是Unix哲学的核心——一个工具干好一件事然后让它们配合。举个例子想找出系统里排名前10的大目录du -sh /home/* 2/dev/null | sort -rh | head -10du -sh只统计每个目录总大小sort -rh按人类可读的数值倒序排head -10留下前十个。这条管道在磁盘告警时非常好用两步就定位到了“谁在吃空间”。我在实际运维里管道思维比任何一条单命令都重要。有些人背了一堆命令遇到问题还是不会用就是因为没有养成“把一个复杂任务拆成几步一步一步喂给管道”的习惯。你能把一个大问题拆成几个小步骤Linux命令的威力才会真正展现出来。2. 用户与权限别再用root裸奔2.1 创建用户的正确姿势很多初学Linux的朋友图省事一直用root或者一个账户到处传。这在生产环境里是非常危险的——你永远不知道是谁在什么时候敲下了什么命令。规范的做法是一个人一个账号按需分配权限。创建用户的常用命令useradd -m -s /bin/bash zhangsan passwd zhangsan-m表示创建家目录-s指定登录Shell为bash。不加-m的后果很严重——用户没有/home/zhangsan目录登录后可能连家都找不着。Debian/Ubuntu系里更推荐用adduser它是一个交互式包装脚本会自动帮你创建家目录、设置密码、生成邮箱等一堆信息。CentOS/Rocky的adduser则可能只是useradd的符号链接行为完全不同。这也是Linux碎片化的一个典型体现换发行版之前一定要确认清楚。创建完用户后如果想给他sudo权限usermod -aG wheel zhangsan # CentOS/Rocky系wheel组有sudo权限 usermod -aG sudo zhangsan # Debian/Ubuntu系sudo组同理这里-aG的意思是“append附加到某组”用-a是追加而不是覆盖。如果漏写了-a等于把人从所有组里踢出来只保留你指定的组大概率直接把用户的sudo权限整没了。2.2 密码策略与密码过期提醒热搜词里有一个“linux密码过期提醒通知”这确实是生产环境的高频需求。Linux密码老化是存在/etc/shadow文件里的但没人会直接手改这个文件正规做法是用chage命令。查看一个用户的密码状态chage -l zhangsan设置90天必须改一次密码提前7天提醒chage -M 90 -W 7 zhangsan这里-M是最长有效天数-W是提前告警天数。还有个-E可以设置账号过期时间比如给外包同事开一个只能用到年底的账号chage -E 2025-12-31 zhangsan我踩过的坑是新创建的用户如果不做任何设置/etc/shadow里的密码时间是空值这在部分系统上会导致“密码策略不生效”。稳妥的做法是在首次登录后强制改密码。chage -d 0 zhangsan-d 0把“最近一次改密码日期”设为unix epoch的0点用户下次登录必须立刻改密码。这个操作在外包、实习生入职离职交接时特别常用。2.3 权限的本质与chmod速查Linux权限非常简单就三个角色属主、属组、其他人配三种操作读r4、写w2、执行x1。数字法就是把这些值加起来。chmod 755 script.sh755拆开就是属主可读可写可执行421组和其他人可读可执行41。这是一般脚本、目录的常规配置。但这里我要特别解释一个坑目录的x权限代表的是“能否进入”。很多新手给目录配成644想着“能看就行”结果发现打不开目录因为他们没有x进入权限。对目录来说r可以列出目录里有什么w可以增删改名x可以进入目录cd进去所以一个可正常访问的目录最低也要711自己全权别人只能进。而普通文件除非它是脚本或二进制否则不建议给所有人加x权限。安全的最小化原则里权限也要够用就好。如果需要批量修改某个目录下的所有文件可以用-R递归chmod -R 755 /opt/app2.4 sudo提权看清每一次身份切换热搜里有个“linux提权”这个在黑客视角里是个攻击话题但从系统管理角度我们更关心的是怎么安全地放权。sudo的配置文件是/etc/sudoers一定要用visudo命令去改不要自己vim /etc/sudoers。因为visudo在保存时会做语法检查你写错了系统会警告而不是等你把sudo搞挂了再后悔。给一个用户授权执行特定命令zhangsan ALL(ALL) /usr/bin/systemctl restart nginx这样只允许他重启nginx不能执行别的systemctl操作更不能切root。比直接给ALL安全得多。我个人踩过的坑授权了systemctl restart nginx结果用户通过systemctl restart nginx.service或者利用systemctl的某些参数绕出去直接改了别的服务。后来的经验是能用systemctl restart nginx就别放systemctl本身精确到命令加上路径是更稳的。还有一条安全习惯执行特权命令前先用sudo -l看一下自己有哪些授权的命令避免反复试错和越权提示。每次sudo执行时系统都会记录到安全的日志文件里多数是/var/log/secure或/var/log/auth.log出问题的时候先翻它基本能定位“谁在哪台机器上干了什么”。3. 进程管理从杀不掉到看得懂3.1 ps一眼锁定“坏进程”你说系统卡了第一件事就是看进程。ps aux这行命令列出所有用户的所有进程CPU、内存、状态、启动命令都出来了。和老的ps -ef相比ps aux把CPU和内存使用率直观地打了出来排查性能问题更友好。特别要关注的是STAT状态列。用ps aux时你会看到一些状态码下面是我实际遇到过的几种S睡眠可中断正常R运行中正常D不可中断睡眠通常是在等磁盘I/O出现多了说明磁盘可能有瓶颈Z僵尸进程这是你要警惕的什么叫僵尸进程就是一个进程已经结束了但它的父进程还没收回它的退出状态于是它在进程表里占着一个“尸体”位置。少量僵尸问题不大但如果数量持续增长说明某个父进程有bug或者被卡死了典型的排查方法ps aux | grep -w Z | grep -v grep然后用ps -o pid,ppid,stat,cmd -p 僵尸进程PID找到它的父进程接下来处理父进程而不是对僵尸进程本身发信号——因为僵尸本来就已经死了kill它毫无意义。3.2 top动态监控里的隐藏信息top命令跑起来是个动态刷新的界面新手容易不知道看什么。我的建议是重点看三块第一行load average系统负载。三个数分别是1分钟、5分钟、15分钟的平均值。判断是否过载不能只看数字要除以CPU核心数。比如8核的机器负载到8才算满载如果1分钟负载远高于15分钟负载说明最近有突发的负载尖峰。第三行%Cpu(s)重点看us用户进程占用和sy系统占用。如果sy奇高说明系统调用过于频繁经常是锁竞争或上下文切换太多。进程列表里的RES和%MEM这是实际物理内存占用比VIRT虚拟内存更具参考价值。top交互模式里按P按CPU排序按M按内存排序按1展开每个CPU核心记不住别的没关系记住这三个按键就够日常用了。3.3 kill的本质信号不是斩杀很多新手把kill想象成“杀毒软件的一键删除”这是完全错误的。kill的本质是给进程发一个信号进程收到信号后自己决定怎么处理。kill PID # 默认发SIGTERM(15)请进程“体面退出” kill -9 PID # 发SIGKILL强制杀死进程无法处理这个信号日常操作里应该先发TERM让程序自己保存数据、清理资源等几秒不行再上-9。一上来就kill -9的坏习惯很可能导致数据库、消息队列这类程序数据损坏。按名字杀进程用pkill按名字模糊匹配是pkill -f但pkill -f会匹配整个命令行有时候会把“正在看这个命令的你”也误杀使用的时候一定要小心谨慎。特别是你想杀nginx时pkill nginx如果你自己在命令行里敲了pkill -f nginx那这条命令本身也包含“nginx”字样容易被自己误伤保险起见还是先pgrep -f nginx确认一下要杀的PID再动手。调整进程优先级用nice启动新进程或renice调整已有进程。比如某个备份任务不想影响线上服务nice -n 10 ./backup.shnice值的范围是-20到19数值越小优先级越高。默认是010就是让它在后台慢慢跑、不跟业务抢CPU。3.4 进程间通信管道、信号、Socket热搜词“linux进程间通信”范围很大但实际运维中最常见的有三种管道Pipe就是|符号一个进程的输出作为另一个进程的输入。这是统计、过滤时最高频的通信方式。信号Signal就是前面说的kill发的信号。进程可以捕获、忽略或处理SIGTERM但SIGKILL无法被捕获。网络Socket不同机器之间的进程通信靠网络端口本机也有Unix Domain Socket比如Nginx和PHP-FPM之间常见的/var/run/php-fpm.sock。排查时最常用的通信问题是“端口被占用”。用ss看端口监听情况ss -lntp | grep :8080-l只看监听-n禁用域名解析不然会卡-t只看TCP-p显示进程信息。看到PID后直接ps -fp PID就能知道是谁占的。3.5 前台后台与nohup别让进程随终端消失用SSH登到服务器上跑一个长任务直接关终端任务就没了——因为终端断开时会向会话里的进程发送SIGHUP。想让它跑在后台几个方式nohup ./longtask.sh longtask.log 21 拆开看nohup忽略挂断信号让命令在后台运行21把标准错误也重定向到日志里不然报错信息会丢。对于已经在前台跑起来的任务先按CtrlZ挂起然后jobs # 查看后台任务编号 bg %1 # 把挂起的任务1转到后台运行 fg %1 # 又拉回前台这套“jobs/bg/fg”组合在调试脚本或者临时调整进程时比nohup更灵活因为不需要中断当前流程。4. 网络与磁盘解决“不通”和“满了”4.1 网络排查从ip到ss以前老教程让你看ifconfig、netstat现在多数新系统默认没装这些。标准答案是新一代工具ip addr # 查看所有网卡和IP地址 ip route # 查看路由表默认网关 ip link set eth0 up # 启用网卡排查“网络不通”的典型链路我用的是先ping内网网关确认链路是否通再ping外网地址确认路由和出口是否正常curl -I http://目标地址确认目标服务是否响应这里有个非常容易踩的坑ping通了不代表服务正常。ping用的是ICMP协议走的是网络层而HTTP/MySQL/Redis这些服务走的是TCP/UDP端口。某个机器能ping通但连不上3306端口那就得检查防火墙、服务状态、端口监听而不用继续纠结在ping上。想测端口通不通没有telnet的时候可以用ncnc -vz 192.168.1.10 3306-v显示详细信息-z表示只扫描不发送数据。几毫秒就能告诉你端口是不是开放。查询TCP连接状态我习惯用ss -s统计摘要如果出现大量TIME_WAIT也别慌。TIME_WAIT是TCP四次挥手后主动断开方必须经历的等待状态通常几十秒后自动消失。只有当数量极大且持续不降才需要考虑调整net.ipv4.tcp_tw_reuse等内核参数但这个问题一般接入接入层/负载均衡设备时才常见个人服务器基本不用太焦虑。4.2 curl不只是下载工具curl在排障里是被严重低估的。想看接口通不通、响应快不快curl -I https://example.com-I发HEAD请求只看响应头不抓正文。想更细致地看整个连接过程耗时curl -w DNS解析: %{time_namelookup}s\n连接建立: %{time_connect}s\nTTFB: %{time_starttransfer}s\n总耗时: %{time_total}s\n -o /dev/null -s https://example.com这个写法把请求过程中各阶段耗时打印出来了。如果time_connect很高通常是网络链路问题如果time_starttransfer高就是服务端处理慢。这条命令在区分“客户端网络问题”还是“服务端性能问题”时能救急。4.3 磁盘满了怎么办热搜词里有一堆磁盘相关说明这是运维命门。首先自查df -h如果/或者某个挂载点使用率到了100%系统会变得极其诡异——进程起不来、写入报错、日志丢失。这时候du是找“元凶”的利器du -sh /home/* | sort -rh | head du -sh /* 2/dev/null | sort -rh | head一层层往下钻找到哪个目录吃掉了大量空间。我处理过一次最经典的情况某个服务疯狂打日志/var/log下有个文件到了50G删掉后系统立刻复活。这里要给新手一个安全建议别急着rm -rf。尤其是删大目录前先看看它是不是软链接、是不是挂载点、有没有其他进程占用。ls -ld /var/log/bigdir lsof D /var/log/bigdirrm -rf是能删东西不假但删错一次的成本可能是你接受不了的。我个人的习惯是先把可疑目录mv到/tmp观察一天确认业务没受影响再删。多花这一步能避免99%的误删后悔局。还有一个更隐蔽的坑df -h显示还有空间但touch新文件却报No space left on device。这是因为inode耗尽了小文件太多塞满了索引节点表。排查方式df -i如果/的已用inode接近100%那就得清理小文件常见于邮件队列、缓存目录、临时文件目录。用find /var -xdev -type f | wc -l可以大致统计文件数量。4.4 挂载磁盘阵列与NAS存储Linux中“盘”不一定在“根目录下”你可以把一块新硬盘或者一个网络存储挂载到任意目录。查当前挂载情况就是df -h和lsblk两块配合。挂载新硬盘的一般步骤fdisk -l # 查看磁盘设备名比如 /dev/sdb mkfs.xfs /dev/sdb1 # 格式化小心数据全没 mkdir -p /data mount /dev/sdb1 /data # 临时挂载要让重启后依然生效需要写/etc/fstabUUIDxxxxx /data xfs defaults 0 0强烈建议用blkid查UUID而不是直接写/dev/sdb1。因为设备名在系统重启后可能变而UUID是不变的。挂载NAS比如群晖、QNAP、其他Linux共享是另一个高频需求用cifs协议mount -t cifs //192.168.1.100/share /mnt/nas -o usernameuser,passwordpass,vers3.0如果想自动挂载fstab里加一行//192.168.1.100/share /mnt/nas cifs credentials/root/.nascreds,vers3.0,_netdev 0 0_netdev这个参数特别关键它告诉系统“等网络就绪后再挂载”否则开机时网络还没起来挂载会失败。如果遇到target is busy卸载不了先看谁在用这个挂载点lsof /mnt/nas fuser -v /mnt/nas找到占用进程让业务停了再umount差不多就解决了。4.5 共享上网让内网机器走你的网关热搜词“linux 共享上网 办法”这在公司内网和实验室环境里都很常见一台Linux机器有外网口另一批内网机器要共用它上网。最朴素的实现是配置iptables的NAT转发echo 1 /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT iptables -A FORWARD -i eth0 -o eth1 -j ACCEPTMASQUERADE的意思是“伪装”把内网机器的源地址换成这台服务器的出口地址。这样内网所有机器只需把网关指向这台Linux服务器的内网IP就能访问外网了。注意ip_forward开关重启后失效要永久生效得写入配置文件。不同发行版位置不同CentOS系在/etc/sysctl.conf加一行net.ipv4.ip_forward 1然后sysctl -p。这个方案在小型办公网络、开发测试环境里非常好用成本为零还不用买路由器。但别在生产大流量场景乱用iptables转发本身性能有限大流量还是要靠专门的路由设备。5. 排查实录与常见问题速查5.1 一个真实问题的排查过程这里分享一次我在测试环境踩的坑。某天同事反馈“服务起不来”第一反应是journalctl -u myservice -n 50看服务日志结果只看到一个Permission denied。于是用运行服务的用户身份去访问配置目录ls -ld /etc/myservice ps -o user,group,cmd -p 服务PID发现服务以nobody用户运行而配置目录的属主是root且权限是700。nobody根本进不去目录。解决方案也不是粗暴地chmod 777而是调整了服务账号为专用的myservice用户把目录chown -R myservice:myservice。问题的根源不是命令不够而是权限模型没想清楚。这类问题排查的通用链路我总结成一句话先看日志再看权限最后看资源。日志能告诉你发生了什么权限告诉你为什么被拒资源告诉你是否到了瓶颈。5.2 高频报错速查表报错信息含义排查/解决方向command not found命令不存在或不在PATH里检查是否安装对应软件包使用全路径/usr/sbin/试一下Permission denied权限不足检查文件属主、组权限对目录检查x权限No space left on device磁盘满或inode满df -h看空间df -i看inodeAddress already in use端口被占用ss -lntpConnection refused目标端口未监听或防火墙拦截ss -lntp确认服务监听firewall-cmd --list-all查防火墙规则Too many open files文件描述符耗尽ulimit -n查看当前限制调大/etc/security/limits.confDevice or resource busy设备或目录被占用用lsof或fuser找出占用进程Read-only file system文件系统变成只读多数是磁盘I/O错误dmesg看内核报错可能需要重启或重新挂载这7个报错可以说覆盖了我这几年遇到的大部分“Linux基础故障”。每一次背后都有具体的故事但排查思路基本都能落到这个表里。5.3 历史命令与自定义快捷键最后分享一个很“基础但实用”的技巧。很多人觉得Linux命令记不住其实最该用的功能是history。history # 列出历史命令 history | grep nginxorder # 搜历史里跟nginx相关的 !nginx # 快速执行最近一条包含nginx的命令慎重先history确认按CtrlR则可以进入反向搜索边输入边匹配历史命令这比翻history省时间得多。如果你想让历史命令带上时间戳执行export HISTTIMEFORMAT%F %T 这条只对当前会话有效想永久生效写入~/.bashrc。加上时间戳之后排查“是谁在什么时间执行了什么命令”就方便多了。我个人的习惯是给高频复杂命令设置别名。把下面几行加进~/.bashrc效率能提升一大截alias llls -alF alias dudu -sh alias portss -lntp alias myipcurl -s ifconfig.me alias ..cd ..保存后source ~/.bashrc生效。别看只是少敲几个字次数多了省下来的时间非常可观。5.4 不要硬背命令要记思想写到这里我特别想多说一句。很多初学者被find、grep、sed、awk、xargs、sort、uniq、wc这一长串工具吓到觉得永远学不完。其实Linux命令设计的逻辑非常统一找输入做处理出输出。你只要先弄明白每个工具的“输入是什么、输出是什么”剩下的就是组装管道的问题了。比如“统计日志里出现次数最多的IP”awk {print $1} access.log | sort | uniq -c | sort -rn | head -10这个组合在那个经典教程里被翻了无数遍但真正理解后你会发现换成统计“最频繁访问的URL”只需要调整awk去取不同的字段。思想通了命令自然就熟练了。遇到不确定的参数优先man 命令名而不是盲目百度。man里面不仅有参数说明还常常有EXAMPLES部分那才是官方给的“实战案例”。一个指令如果你已经能自己翻man搞明白说明你已经开始从“背命令”跨向“用命令”了。这个系列的第二篇就到这里内容没有按照教科书顺序从a讲到z而是尽量从真实场景出发把“文本处理、权限、进程、网络磁盘、排障思路”这几块最常用的基础指令梳理了一遍。我在实际使用中最大的体会是这些指令单独拎出来都不难真正的门槛在于遇到问题时能不能想起“哦这个需求可以用哪几个命令拼出来”这个能力只能靠一次次真实排障喂出来。所以建议你把文章里的命令都亲手敲一遍哪怕就是看看输出格式也比干读有价值得多。