ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux命令实战手册:高效运维与开发部署的高频命令全解析

Linux命令实战手册:高效运维与开发部署的高频命令全解析 干了这么多年运维和开发我越来越觉得Linux命令这东西不是背得多就厉害而是用得准、组合得妙才值钱。网上一搜“Linux常用命令大全”能出来几百条但实际生产环境里你每天反复敲的其实就那几十条。今天这篇我不打算做成一个面面俱到的词典那是man page干的事。我想换个角度从运维开发日常最常遇到的几类场景出发把那些真正高频、真正能解决问题的命令串起来讲附带参数细节、组合用法和我个人踩过的坑。不管你是刚入行的运维新手还是写代码之余要自己部署服务的开发只要你在跟Linux打交道这篇文章都能让你少走点弯路。文章里涉及日志搜索、进程排查、网络定位、磁盘清理、部署发布、容器操作这些核心场景我会把每个命令的使用边界和“为什么这时候用它”讲明白而不是简单罗列参数。1. 日志与文本处理一天里用得最多的命令组合1.1 grep过滤日志的基本功比你想的更强大日志排查是运维开发的日常。服务出问题了第一反应就是去看日志。但日志文件动辄几百MB甚至几GB你要从里面把关键信息捞出来grep就是你最趁手的工具。很多人用grep就只会“grep error xxx.log”其实把它几个常用参数吃透效率能翻好几倍。我最常用的几个参数组合# 在日志中搜索包含 error 的行忽略大小写并显示前后各5行上下文 grep -i -n -A 5 -B 5 error app.log # 搜索不包含某个关键词的行比如刷掉健康检查的噪音 grep -v healthcheck app.log # 统计某个错误出现的次数 grep -c Connection timed out app.log # 只输出包含匹配的文件名不显示具体内容适合批量排查多个日志 grep -l OutOfMemoryError /var/log/app-*.log这里面的-A和-B参数特别实用。老实说大多数时候你搜“error”真正有价值的不是那一行error本身而是它前面发生了什么、后面又导致什么。比如Java应用打出一堆异常堆栈如果你只匹配第一行异常没有-A 20把堆栈带出来你根本定位不到问题代码。我习惯的做法是先grep -c看数量再grep -A 20 -B 5看具体上下文最后带着时间戳和日志片段去排除。还有一个容易忽略的细节在日志搜不到东西的时候不一定是没报错有可能是日志级别设置太高或者应用写日志的文件跟你查的不是同一个。所以搜之前先确认日志路径、日志级别、是否有滚动切割这比搜本身更重要。1.2 tail -f与grep联用实时跟踪线上问题线上出问题的时候日志还在不断滚动写入这时候你不可能反复去grep整个文件tail -f就是干这个的。配合grep之后你可以只盯着跟你问题相关的日志流。# 实时跟踪日志并过滤关键词 tail -f app.log | grep --line-buffered Exception # 看最后500行然后退出 tail -n 500 app.log # 同时跟踪多个日志文件 tail -f app.log error.log access.log这里有个细节我一开始经常弄错管道给grep之后grep默认是块缓冲的也就是日志内容不会立即显示出来会攒一批再输出实时性很差。加上--line-buffered让grep以行为单位刷新输出才能真正做到“实时”。生产环境里我经常用这个组合来快速定位问题爆发点。比如支付回调一直失败我就tail -f /var/log/app/payment.log | grep --line-buffered callback然后去前台触发一次操作命令行里立马能看到链路日志比自己翻半天文件高效太多。1.3 awk与sed提取字段和批量改文本的利器如果说grep负责“过滤行”那awk就是“切列”的王者。日志里常见的格式是时间、级别、线程、消息用空格或分隔符分开。当你需要统计某个维度的数据时awk能直接输出。# 从日志中提取第1列通常是时间和第4列并按时间排序 awk {print $1, $4} app.log | sort # 以冒号作为分隔符提取第2列 awk -F: {print $2} app.log # 统计日志中不同接口的调用次数按访问量降序 awk {print $7} access.log | sort | uniq -c | sort -rn | head -20那段统计访问量的命令是我日常用得最频繁的。它本质上是一个组合管道awk提取URL列sort排序uniq -c去重并计数sort -rn按数字倒序排列head取前20。一个复杂的统计需求四段管道就解决了。sed则专注于文本编辑。最常见的两个场景批量替换文本内容、删除指定行。# 把配置文件里的旧域名替换成新域名并直接修改文件 sed -i s/olddomain.com/newdomain.com/g nginx.conf # 删除配置文件里所有注释行和空行方便排查配置 sed -i /^#/d; /^$/d nginx.conf注意sed -i的-i参数是直接修改文件这是个危险操作。我建议第一次执行的时候先不带-i跑一遍确认输出结果正确再真正落地。实际操作中我吃过亏一条不严谨的替换正则直接把一个关键配置文件的内容搞乱了还好有备份。改配置文件之前无论如何都先复制一份cp xx.conf xx.conf.bak这应该成为肌肉记忆。1.4 less与zcat大日志文件也能轻松查动不动好几个GB的日志用vim直接打开会卡死用cat会把终端刷爆。这时候less是你的最大依仗。它支持分页查看、向上向下翻页还能直接按/搜关键词、按n跳到下一个匹配。更爽的是less在打开大文件时不是一次性加载全量内容所以几GB的日志也能流畅操作。# 打开大日志文件 less huge.log # 进入less后按 ShiftG 跳到底部按 g 跳到头部 # 按 / 输入关键词搜索按 n 下一个按 N 上一个 # 按 F 键 tail -f 效果实时跟踪文件尾部还有一个实际生产中非常常见的场景日志已经被logrotate切割了变成.gz压缩包。这时候不需要解压再查直接用zcat或zgrep# 直接查看压缩日志内容 zcat app.log.2.gz | grep ERROR # 压缩包内容搜索关键词比 zcat 管道的效率略高 zgrep OutOfMemoryError app.log.2.gz如果你的日志目录里压缩包很多想一次性搜所有压缩包可以用zgrep 关键词 /var/log/app-*.gz这比逐个解压再grep节省大量时间。2. 进程与系统资源从“服务挂了”到定位根因的完整链路2.1 ps aux先搞清楚机器上到底在跑什么接到线上告警第一步不是急着重启服务而是先看系统当前的状态。ps aux是我输入频率最高的命令之一它能列出当前所有进程的详细情况。跟ps -ef相比ps aux的格式里多了CPU和内存占用百分比排查资源问题时更直观。# 查看所有进程按CPU占用降序排列取前10 ps aux --sort-%cpu | head -10 # 查看所有进程按内存占用降序排列 ps aux --sort-%mem | head -10 # 查找某个特定服务/程序的进程PID ps -ef | grep java这里有个新手经常踩的坑用ps -ef | grep java搜进程会把grep自己那行也搜出来有时候还会产生一条“grep java”的杂音。更干净的方案是用pgrep -f java或者ps -C java。pgrep直接输出PID特别适合在脚本里配合kill使用# 找到所有含 java 的进程PID pgrep -f java # 根据PID查看进程的详细信息 ps -p 12345 -o pid,ppid,%cpu,%mem,cmd定位到具体PID之后一定要学会看这个进程的父进程。很多时候你杀掉进程发现没一会儿它又起来了——因为supervisord或systemd会自动拉起它。这时候你杀的根本不是源头正确的做法是停掉守护进程或服务再处理业务进程本身。2.2 top与free三个命令判断资源瓶颈CPU满、内存不够、磁盘IO慢这些性能问题的第一现场基本靠top和free来开荒。top不必多说进入界面后按P按CPU排序按M按内存排序按1显示每个CPU核的使用情况按c显示完整命令行。这些都是基本操作。但top有一个坑它显示的是实时数据如果只看一瞬间很容易误判。比如某个瞬间CPU飙到100%可能只是进程启动时的一个尖峰。我更习惯用top -b -n 1把当前状态以批处理模式输出一次边缘脚本里采集数据很好用。# 批处理模式输出一次top结果适合脚本采集 top -b -n 1 | head -30 # 查看内存使用情况单位字节 free -hfree -h这个命令重点看两列available和used。很多没经验的人一看used那一行数值很大就慌觉得内存不够了但实际上Linux会尽量把空闲内存用作文件缓存buff/cache这不算真正的占用。真正要盯着的是available这一列它代表在不触发swap的情况下还可以分配给程序的内存。我见过好几次“误报内存告警”的例子原因就是不看available只看used。内存问题要结合进程维度看用ps aux --sort-%mem | head -10找出最占内存的进程再判断是内存泄漏还是单纯的配置分配过高。如果重启进程后内存占用又慢慢涨上来大概率是泄漏这时候就该考虑调优或提bug单了。2.3 systemctl与nohup服务启停的前台与后台思维现在主流的Linux发行版都跑systemd服务管理基本都走了systemctl# 服务相关操作 systemctl status nginx # 查看服务状态包括主进程PID、内存、日志位置 systemctl restart nginx # 重启服务 systemctl enable nginx # 设置开机自启 systemctl daemon-reload # 修改service文件后重载配置systemctl status是最值得关注的一个命令它不光告诉你服务是active还是failed还会直接带出最近几行日志和主进程的PID省掉你还要去翻日志文件的一步。但dev环境里尤其是自己临时起的开发进程往往就没那么规范。这时候nohup和就派上用场了。用它们脱离终端运行进程# 后台启动应用输出重定向到app.log nohup java -jar app.jar app.log 21 # 记录后台进程PID后续好管理 echo $!这里有个细节为什么标准输出和错误输出都要重定向因为如果你只写 app.log进程的错误输出还是会打到终端上而终端一关这个进程就可能因为管道断裂产生各种奇怪问题。21是把标准错误文件描述符2重定向到标准输出文件描述符1的同一位置这样所有日志都进同一文件排查时也不用开俩窗口。如果要跟后台进程打交道更顺手jobs -l可以列出当前终端的后台任务fg把它调回前台CtrlZ挂起bg放到后台继续跑。这套组合在多任务编译、启动多个微服务的时候特别好用。2.4 dmesg与kill内核日志和进程终结者的正确打开方式进程突然消失、服务器负载莫名其妙飙升、硬件报错这些场景往往在应用日志里查不到原因。这时候dmesg能帮你看到内核层面的信息尤其是OOM Killer内存耗尽杀进程和硬件IO错误# 查看内核环形缓冲区日志通常是最后一次系统启动以来的信息 dmesg | tail -50 # 查看是否发生过OOM KillOOM Killer杀进程往往整行写的很明确 dmesg | grep -i out of memory # 更精准地看某个进程被kill的痕迹 dmesg | grep -i killed process我前几年排查过一个非常诡异的问题一个Java服务不定期消失应用日志里没有任何异常重启后又能跑几天。查了jvm参数、GC日志都没有头绪。后来执行dmesg -T | grep -i oom发现是Linux内核把进程判定为内存占用超标直接触发了OOM Killer。问题根因是机器上另一个缓存服务把内存吃光了系统为了自保挑了个进程杀掉。这里有个坑在内存紧张时被选中的往往不是占用最大的进程而是根据内核算法选出来的“牺牲品”不一定是你以为的那个。至于kill命令很多人只会kill -9但-9是SIGKILL强杀进程不给他清理资源和保存状态的机会是最后手段。一般的优雅停止流程应该是# 先发SIGTERM让进程自行收尾 kill -15 12345 # 等几秒如果进程还在再考虑SIGKILL kill -9 12345生产环境里进程自己写的临时文件、持有的数据库连接、缓存的堆内数据都需要在SIGTERM信号里做清理。你上来就kill -9很可能造成文件损坏或脏数据。这是我在早期运维中频繁犯的错现在只要不是进程完全卡死一律先-15再-9。3. 网络排查与连通性验证从“访问不了”到确认问题在哪层3.1 链路分层的排查顺序ping、telnet、curl网络问题是运维开发最头疼的一类因为它涉及链路环节多客户端、DNS、防火墙、负载均衡、服务端进程、服务端防火墙……排查的时候必须有层次感。我自己的习惯是按OSI模型从下往上查先确认网络通不通再确认端口通不通最后确认HTTP层有没有问题。# 最基本的三层连通性测试 ping -c 3 10.0.0.5 # 确认某个TCP端口是否可达 telnet 10.0.0.5 8080 # 或者用nc更可控能配置超时时间 nc -vz -w 3 10.0.0.5 8080ping通则网络通ping不通未必网络不通也可能是对方禁了ICMP。这个要记住不能一ping不通就认定网络断了。telnet ip port看端口能连上会显示Connected连不上会卡住直到超时。nc -vz -w 3是我更推荐的因为可以设置超时不像telnet那样挂半天不返回。从开发的角度能ping通、能telnet到端口但业务依然访问不了那问题大概率出在应用层。这时候就该curl上阵了。3.2 curl不只是“请求一个URL”curl是开发和运维之间的桥梁。开发在本地写好的接口到服务器上能不能通、返回什么状态码、响应有多快全靠curl一手验证。日常我的高频curl用法# 只查看响应头快速判断服务是否存活 curl -I http://localhost:8080/ # 查看完整请求响应打印HTTP状态码、耗时等数据 curl -w \nHTTP状态码%{http_code}总耗时%{time_total}sDNS耗时%{time_namelookup}s\n -o /dev/null -s http://localhost:8080/ # 发送POST请求携带JSON体开发调试接口必备 curl -X POST -H Content-Type: application/json -d {name:test} http://localhost:8080/api/create # 模拟真实浏览器环境访问有些服务会校验User-Agent curl -A Mozilla/5.0 (Windows NT 10.0; Win64; x64) http://example.comcurl -w里的那些格式化参数是我每台服务器上都会用到的。一个接口响应慢你得搞清楚慢在哪一段DNS解析慢、TCP建连慢还是服务端处理慢-w配合%{time_namelookup}、%{time_connect}和%{time_total}就能把几段耗时拆出来。我有个判断习惯time_connect到time_starttransfer之间差距大说明服务端处理慢跟网络关系不大time_namelookup如果超过几百毫秒可能你的内网DNS有问题。还有个常用技巧用-o /dev/null丢弃响应体内容。因为很多接口返回体巨大打印到屏幕上纯属浪费我们关心的是状态码和耗时。这个习惯能让你在排查接口性能时不被海量响应内容干扰。3.3 ss与tcpdump端口监听状态和精确抓包端口起没起来、连接数是不是爆了、有没有大量TIME_WAIT这些问题以前用netstat现在我更推荐ss。它比netstat快得多尤其在高并发场景下。netstat在大连接数时会遍历所有socket然后输出ss直接读内核socket信息快一个量级。# 列出所有监听中的TCP端口并显示对应进程 ss -lntp # 查看当前所有TCP连接并按状态统计 ss -s # 查看所有连接到某个端口的连接 ss -tnp state established ( dport :8080 )重点解读一下ss -lntp-l只显示监听LISTEN中的socket-n不做域名反解直接显示IP和端口不加-n会慢且容易卡-t只看TCP-p显示进程信息。这一条命令是我在排查“端口被占”时的首选里面直接能看到是哪个进程PID占用了端口省去lsof的额外步骤。排到更底层的网络问题时tcpdump是抓包利器# 抓取特定端口的所有流量保存到pcap文件方便用wireshark打开 tcpdump -i any -s 0 -w /tmp/capture.pcap port 8080 # 抓取特定主机与目标IP之间的流量并打印详细内容 tcpdump -i eth0 host 10.0.0.6 and port 80 -vvv # 抓取HTTP请求内容ASCII格式显示过滤GET/POST请求 tcpdump -i eth0 port 80 -X -A说实话tcpdump输出标准格式一开始会看不太懂但这东西在排查“网络包根本没到达服务器”这种问题时无可替代。有一回客户反馈请求偶尔超时我从应用日志、接入层日志都找不到规律最后用tcpdump抓包发现某些请求在TCP层就开始重传丢包率不稳定一查是机房交换机某条链路光衰异常。这种问题没有抓包数据反馈给网络组根本说不清是谁的责任。3.4 域名解析与本地hosts的临时上线技巧开发环境偶尔需要“用线上的规则去访问一个新部署的服务”或者为了测试新版本希望域名指向某台测试服务器。改DNS生效慢且有全局影响临时快速方案是修改/etc/hosts# 查看当前域名解析结果 getent hosts example.com # 或老办法 ping example.com # 临时指定某个域名解析到指定IP echo 10.0.0.8 staging.example.com /etc/hostsgetent hosts比ping好在哪ping会因为对方主机禁ICMP而误判getent只查域名解析不受禁ping影响。改hosts这种操作要非常清楚自己的行为它只影响本机对该域名的解析且优先级高于DNS。用了就得记住不然排查半天怎么域名指向不对——很可能是你自己之前加的hosts记录还在生效。4. 磁盘、文件与权限这些细节决定你在服务器上能活多久4.1 df与du磁盘爆满时如何快速定位元凶“磁盘满了”大概是运维告警里出现频率最高的词。服务一写日志就报No space left on device或者数据库直接拒绝写入这时候你需要既看到整体水位也能快速定位到具体是哪个目录吃掉了空间。# 查看各分区空间使用情况人类可读格式 df -h # 查看当前目录下各个子目录的占用大小定位大文件目录 du -sh * | sort -h这两个命令一个看文件系统层级一个看目录层级。df -h输出里要注意有没有哪个分区Use%到了90%以上特别要盯/根分区因为它一旦写满连登录都可能出问题。du -sh *会统计当前目录下每个文件夹的大小sort -h按人类可读的数字大小排序一眼就能看出哪个目录是“磁盘杀手”。一个常见的定位思路是在根目录逐级du下来先cd /再du -sh * | sort -h找最大的目录进去再执行一遍几轮下来就能锁定具体是日志目录、临时目录还是某个数据库数据目录出了问题。这个过程可以写成脚本但手工执行时记住du对大目录第一次统计会比较慢耐心等。需要注意df显示的used空间和du统计出来的文件大小有时候对不上。原因是文件可能被进程打开但已经删除deleted状态文件系统上空间没释放但你du已经看不到它了。排查这种情况要结合lsof L1# 查看被删除但仍被进程占用的文件 lsof -nP | grep deleted遇到这种情况直接找对应进程并重启/重载它空间才会真正释放。我遇到过一次奇怪的“磁盘持续占满但du找不到大文件”就是这个原因——一个进程把大日志文件删除后没有关闭文件描述符日志还在继续写入这块已删除的inode上。这类问题基本靠这个命令定位。4.2 ln -s软链接与cp/rsync发布部署的高频操作软链接在部署上的价值容易被轻视。权限、备份、切换版本都离不开它。尤其在发布应用时用软链接做版本切换是一个极其稳妥的模式# 创建当前版本软链接 ln -s /opt/app/releases/app-1.2.3 /opt/app/current # 指向新版本目录 ln -sfn /opt/app/releases/app-1.3.0 /opt/app/current # 重启服务服务仍用 /opt/app/current 这个路径 systemctl restart myapp这里的核心逻辑是配置文件、systemd服务脚本都指向/opt/app/current发布时只需要把新版本放到releases目录下然后把软链接current指向新版本最后重启服务即可。一旦新版本有问题一条命令切回旧版本。这比直接覆盖替换文件不知道安全多少倍。ln -sfn中-s是软链接-f是强制替换-n是为了避免符号链接替换时出现“把链接当目录处理”的困惑。日常传文件和同步目录scp和rsync是两大主力。单文件传递用scp目录级、增量同步用rsync# 复制单个文件到远程服务器 scp ./app.jar root10.0.0.5:/opt/app/ # 增量同步整个目录保留权限、属主并删除远端多余文件 rsync -avz --delete ./build/ root10.0.0.5:/opt/app/www/rsync这个命令的-a是归档模式保留权限时间戳等属性-v显示进度-z传输时压缩--delete让远端目录跟本地严格一致。对于发布前端静态资源、同步代码、备份数据这种需求rsync几乎是最优解。需要注意rsync同步操作是有方向性的千万别把源远程和目标写反我有一次就是写反了把远端一个老版本的目录同步回本地挨个覆盖了新文件差点酿成事故。4.3 chmod、chown与权限模型文件的读与执行权限不搞清楚会被坑权限问题几乎每个新手都遇到过文件明明在可程序就是报Permission denied。Linux的权限模型本质是一个用户对文件的操作能力由“所属用户、所属组、其他用户”三段权限位决定。用ls -l看文件开头那一串字符比如-rwxr-xr--第2-4位是all对owner的权限第5-7位对group第8-10位对其他人。# 给文件所有者增加执行权限 chmod ux deploy.sh # 将目录及其下所有文件的属主和属组改成www用户 chown -R www:www /opt/app/ # 查看某个文件的详细权限和属主 ls -l /opt/app/deploy.sh很多开发在本地用root用户写代码传到服务器上之后发现服务起不来原因往往就是文件属主是root服务却以www用户运行根本没权限读或执行。这种问题排查成本极低看一眼ls -l就能定位但经历过的人会从此养成习惯上传部署包之后先确认属主和权限再启动服务。还有一个常见坑修改权限时对目录用了错误的权限位。对目录而言r权限意味着能列出目录内容x权限意味着能进入目录或穿越它。只有一个都没有的话即使你知道路径也无法访问目录内的文件。部分公司安全基线会要求目录权限为755文件权限为644这个设定就是保证“所有者可写其他人和组可读可执行但不可写”。4.4 定时任务与日志切割抢占磁盘空间的长期治理排查完磁盘占满的问题通常还要做长期治理否则过几天又爆。最常用的手段是logrotate按天切割压缩日志和crontab定时清理临时文件。# 查看某个日志文件的切割配置 cat /etc/logrotate.d/nginx # 手动强制执行一次logrotate logrotate -f /etc/logrotate.d/nginx # 列出当前用户的所有定时任务 crontab -l # 编辑当前用户的定时任务 crontab -elogrotate配置里核心就几项daily按天切割、rotate 7保留7份、compress压缩旧日志、copytruncate解决应用持续写同一个文件问题。配置好之后日志目录基本能长期维持在一个稳定水位。定时任务这块有个经验写crontab时一定要把脚本路径写成绝对路径并且在脚本开头source相关的环境变量文件。因为crontab执行环境中PATH非常精简很可能你在终端里正常的命令到定时任务里就“command not found”了。排查crontab不生效的时候第一件事就是把脚本手动执行一遍并重定向输出到日志文件里看看究竟报了什么错。# 一个典型的定期清理脚本写法 0 3 * * * /usr/bin/find /var/log/app/ -name *.log -mtime 7 -delete /var/log/clean.log 21这条命令每天都凌晨3点删除7天前的.log文件。find的-mtime 7表示修改时间在7天以上。删除操作在生产环境要特別小心建议先不加-delete跑一遍看输出列表是否都符合预期再正式启用。5. 开发部署日常Docker、文本编辑与脚本调试的高频命令5.1 docker常用命令容器时代的运维开发必备现在部署一个服务几乎绕不开容器。Docker相关命令在运维开发中的使用频率已经不亚于传统的systemctl。但Docker命令体系庞大实际工作中真正高频的其实就这些# 镜像相关的三个核心操作 docker images docker pull nginx:1.25 docker rmi image_id # 容器生命周期管理 docker ps -a # 查看所有容器包括停止的 docker start/stop/restart container docker rm container # 进入正在运行的容器内调试 docker exec -it container /bin/bash # 查看容器实时日志 docker logs -f --tail 200 container # 查看容器占用的系统资源 docker stats --no-stream每次排查容器问题我基本上先跑docker ps -a确认容器当前状态是运行还是退出再用docker logs -f --tail 200看日志。如果容器一直处于不断重启的崩溃循环就需要查看容器的退出码和最近一次启动的原因docker inspect container能把容器的详细配置、退出码、挂载卷、网络模式都列出来。特别是OOMKilled这个状态会直接在inspect结果或stats里体现出来。一个高发问题的定位技巧容器内服务监听的是容器自己的ip不是宿主机ip。如果你在宿主机上curl localhost:8080失败了不代表容器内服务有问题很可能是没有做端口映射或映射端口没写对。排查思路要分清楚“容器内”和“宿主机”两个维度先docker exec进容器里面验证服务是否正常监听再回头看docker ps的PORTS列端口映射是否合理。5.2 文本编辑与快捷键vim的高频操作足够应付大多数场景开发者在服务器上改配置、改脚本用的最多的编辑器还是vim。很多人一进vim就手足无措其实只需要掌握几个核心模式切换和常用命令效率就远超在Windows里改完再上传。vim最基本的心智模型是普通模式默认、插入模式按i进入、命令行模式按:进入。日常高频命令# 打开文件直接定位到第100行 vim 100 app.log # 普通模式下 # gg 跳到文件头 # G 跳到文件尾 # dd 删除当前行 # yy 复制当前行p粘贴 # /关键词 搜索n下一个 # 命令行模式下 # :set number 显示行号 # :%s/old/new/g 全文替换跟sed -i类似 # :wq 保存退出:q! 不保存强制退出我见过的很多人都栽在“不知道怎么退出vim”上。这里给大家一个明确路径按Esc确保回到普通模式再输入:q退出如果文件有改动就:wq保存退出。如果觉得无论如何都退不出去可以直接:q!放弃修改强制退出。记住这三条在任何机器上都不会被困在vim里。还有一个小技巧vim可以配合grep来做“找到然后编辑”的流程。比如你想看看所有包含“timeout”的配置行可以先grep -n timeout nginx.conf看到行号然后vim 行号 nginx.conf直接定位过去。这比在vim里搜索更直观也和题目的“命令组合”思想一致。5.3 Shell脚本调试与执行set -x还原真实运行过程把常用操作沉淀成脚本是运维开发减少重复劳动的核心。但写脚本容易调试脚本才是真功夫。很多线上问题往往不是业务逻辑错而是脚本在特殊条件下执行的结果跟预期不一致。要找到问题我最推荐的做法是bash -x# 以调试模式执行脚本会打印每条命令展开后的实际执行内容 bash -x deploy.sh # 更细粒度在脚本内部开启调试往往写在脚本第一行 #!/bin/bash set -x # ...脚本内容... set xset -x的效果是每条命令执行前先把它的完整展开结果打印出来。什么意思比如你脚本里写了echo $APP_HOME运行时你会看到实际打印的是echo /opt/app这就能立刻发现变量有没有正确赋值。脚本排查90%的问题都可以靠这个命令解决。还有一个容易被忽略的脚本问题变量没加引号导致空格被拆分成多段。写命令的时候$APP_NAME一定要加双引号尤其是文件名或字符串可能包含空格的时候。用set -x执行一遍这类问题会原形毕露。5.4 构建与进程守护从手动启动到可靠运行开发环境里进程死了你可能没注意到等要测试时才发现服务早已挂掉。这里给一个简易的进程守护思路写一个脚本检查进程是否存在不存在则拉起然后配合crontab定时执行。#!/bin/bash if ! pgrep -f app.jar /dev/null; then nohup java -jar /opt/app/app.jar /var/log/app/app.log 21 echo $(date) app restarted /var/log/restart.log fi这个脚本每5分钟检查一次进程如果app.jar不在运行就重新拉起并记录重启时间。配合crontab实现*/5 * * * * /opt/scripts/check_app.sh通过重启记录能及时发现服务频繁崩溃的规律。注意脚本里用pgrep -f app.jar而不是只写pgrep java因为后者会匹配到所有跟java相关的进程导致判断失真。6. 高频面试题背后的命令本质能答不等于能干6.1 几个经典面试题和它们的标准解面试中被反复问到的Linux命令题其实都是上面这些场景的具体变形。我梳理几个高频问题把标准答案和面试官的考察点放在一起比较面试题标准答案面试官真实考察点如何查看进程占用CPU最高top进界面按P或ps aux --sort-%cpu是否知道top的交互快捷键而不只是会“打开top看一眼”如何查看某个端口被谁占用ss -lntp或lsof -i:8080是否理解LISTEN状态和进程PID的对应关系如何查找超过1GB的文件find / -type f -size 1G是否会用find的size条件能否处理权限报错噪音如何查看日志末尾100行并持续监控tail -n 100 -f app.log是否清楚-n和-f组合使用时是从最近100行开始跟进如何给日志按天切割并保留7天配置logrotate是否真正管理过日志而不是只会手动清理这些问题都不算偏门但能把每个命令背后的场景、参数组合、输出格式都讲清楚的人往往才是真正上过生产环境的。背答案的人只会说“用top看”问到底哪个进程占内存、怎么看它的启动参数、怎么确认是不是内存泄漏就卡壳了。6.2 面试追问里真正想听的“实操经验”我参与过不少技术面试给候选人的感觉是面Linux命令淘汰人的往往不是“不知道是什么命令”而是“只知道命令不知道场景”。面试官真正想听到的是你面对一个实测问题的完整思考路径。比如“服务器CPU突然飙到100%你怎么排查”很多人第一反应就是top看哪个进程高这没错但只答这一层是不够的。有经验的人会往下追问CPU是用户态高还是内核态高如果是内核态高可能是磁盘IO中断频繁或者网络包过多如果是用户态高再pstack或jstack看线程在做什么。这些“再下一步”的动作才是命令功底和实战经验的真正分界线。再比如“日志一直在增长你如何在不停止服务的情况下查看最新报错”背题的人会说tail -f有经验的人会补一句“配合grep --line-buffered 过滤关键词并且注意实时日志里噪声多先想清楚要搜什么特征”。这个补充就是日常实战打出来的东西不是看书看得会的。6.3 从“背命令”到“搭命令体系”的进阶思路面试题的核心价值不在于让你会答而在于让你形成一套命令组织的思维框架。我自己工作久了之后记忆方式早就不是一个个命令孤立地背而是“遇到某一类问题脑子里自动出现一条命令组合管道”日志分析问题 →zgrep - grep - awk - sort - uniq -c - sort -rn - head进程异常问题 →ps aux --sort-%cpu - pgrep -f - ls -l /proc/PID/cwd - systemctl status网络不通问题 →getent hosts - ping - telnet/nc - ss -lntp - curl -w - tcpdump磁盘膨胀问题 →df -h - du -sh * - find -size 1G - lsof L1 - logrotate每个“→”都是一个判断分支这一步的输出决定下一步的选择。这种思维方式一旦建立你面对任何一台未知的Linux机器都不会慌因为你知道手上的工具能覆盖哪些场景、卡在哪一步应该用什么命令。这也是为什么我强烈建议读者不要只看命令大全而是按“场景-问题-命令组合”的维度去整理自己的笔记。同一个命令在不同场景下参数完全不同比如tail -f看实时日志、tail -n 500看历史片段它俩解决的问题根本不一样。把命令和场景绑在一起记忆才是生产级的能力。我个人习惯是在笔记本里维护一份“故障排查命令速查表”每碰到一个新的线上诡异问题就把当时的完整排查链路记录下来。时间久了这份文档比任何网上的命令大全都有价值因为上面记的是自己机器上真实跑过的命令、真实的报错、真实的解决路径。最后分享一个我自己坚持了很多年的小习惯在服务器上新建用户后第一时间把vim、grep、tail这些高频命令的常用别名配置进~/.bashrc比如alias grepgrep --colorauto、alias llls -lh。这些细节看似不起眼但长期下来能省下大量重复输入的时间。毕竟生产环境的每一分钟都很宝贵。
返回列表