早上到工位,打开终端,一天的活儿基本都在这几行命令里了。这个备忘录我断断续续攒了好几年,从最早只会ls和cd,到现在处理线上问题、写脚本、排查网络、收拾容器,靠的全是这些日常命令的积累。今天把这些东西整理出来,不是想做成什么大全,就是把我真正高频使用的、踩过坑的、容易记混的命令和用法都摊开说说,顺便讲讲每个命令背后的判断逻辑——知道为什么用,比记住怎么用更重要。
这份内容适合谁?刚入行的运维和开发可以把它当速查手册,有几年经验的朋友可以对照看看有没有漏掉什么实用技巧。我尽量不写教科书式的完整参数列表,那些查文档就有,我写的一定是实际工作里用得上、还容易翻车的部分。
1. 先说说我整理这份备忘的思路
1.1 这份备忘的定位:不是命令大全,是工作流速查
我在整理命令的时候发现一个规律:真正高频用到的东西其实就那么几十条,剩下几百条都是低频工具,用到再查也不迟。所以这份备忘的核心逻辑不是按字母序堆命令,而是按工作流来组织——从你登录服务器开始,看资源、查进程、找文件、改配置、看日志、排查网络、操作数据库、提交代码,一条线下来全是真实场景。
比如查问题的时候,你的思路应该是先看机器整体状态(top、free、df),再定位具体进程(ps),然后看日志(tail、journalctl),最后才是猜测原因和验证。如果一开始就钻进某个应用日志里翻,很容易忽略系统层面的问题,比如磁盘满了、内存不够、CPU跑满。我在备忘录里特意把命令按这个排查顺序排列,用的时候顺着走就行。
另外我还给自己定了个规矩:凡是踩过坑的命令,一定要在旁边记一句“当时是怎么翻车的”。比如chkdsk跑坏道检查时卡了一晚上,比如rm -rf删错目录,比如docker attach进去之后按Ctrl+C把容器停掉了。这些真实教训比任何参数文档都值钱,时间久了就变成自己的直觉了。
1.2 三个整理原则:高频优先、场景关联、记录坑
先说高频优先。我统计过自己日常操作,大约20%的命令覆盖了80%的场景。ls、cd、grep、ps、top、tail、vim、git status、git log、docker ps,这些天天都在用,必须形成肌肉记忆。那些一个月用不到一次的命令,比如traceroute、tcpdump的复杂组合,知道关键词就行,需要的时候再去查具体语法。
第二个原则是场景关联。我从来不按“网络命令有哪些”这种分类去记,而是按“端口不通怎么办”“磁盘满了怎么排查”“日志刷太快怎么定位”这种场景来组织。因为实际遇到问题时你的记忆是场景化的,不是分类化的。举个例子,端口不通可能是服务没起、防火墙挡了、监听地址错了、DNS解析不对,每种原因对应的排查命令完全不同,只有把命令放进场景里才有意义。
第三个原则是记坑。cmake、编译、权限、路径,凡是让我卡住超过十分钟的问题,我都会在备忘里单独记一行。时间久了你就发现,工作里最大的时间杀手不是你不会用命令,而是同一个坑踩了好几次。后面我会单独用一整章来写这些坑,那部分是我最想分享的。
2. 每天开机必看的资源与进程命令
2.1 系统负载三件套:top、free、df
先看整体再查细节,这是解决一切服务器问题的第一步。登录机器之后,我习惯先跑三个命令:top看CPU和负载,free看内存,df -h看磁盘。这三个命令各有各的门道。
top命令输出的第一行是负载均值,三个数字分别代表1分钟、5分钟、15分钟的负载。如果15分钟的值很高但1分钟的值在降,说明负载在缓解;反过来1分钟突然飙升而15分钟很低,说明刚刚有突发流量或定时任务。光看数字不够,要结合CPU状态那一行的us、sy、wa来判断——us高说明应用在跑计算,sy高说明系统调用频繁可能是上下文切换过多,wa高说明IO在拖后腿。很多人遇到负载高就直接kill进程,其实wa高的时候应该先看磁盘,可能是某个日志在疯狂写入。
free -h在Linux上有个容易误读的地方:available那列是真正可用的内存,而free列很小不代表内存不够,因为Linux会尽量把空闲内存用作page cache。我记得有一次同事看到free只剩200MB就急着加内存,实际上available还有6GB,完全没必要。判断内存是否紧张,看available而不是free,如果available持续低于总内存的10%并且发生swap交换,才需要处理。
df -h看磁盘使用率是常识,但我还想强调一个细节:df看到的是文件系统层面的使用率,如果你删了大文件但空间没释放,八成是有进程还在持有这个文件。这种情况用lsof | grep deleted找出还占着文件的进程,重启或kill它,空间才会真正回来。这个坑我踩过好几次,删除日志后发现磁盘还是满的,排查半天才反应过来。
2.2 查进程:ps命令的正确用法
ps命令的参数组合我见过太多人记混了,其实常用的就两种。一种是ps -ef,另一种是ps aux,两者显示的信息基本一样,区别只是格式稍有不同。我习惯用ps -ef | grep stackoverflow来定位某个进程,然后拿第二列的PID去操作。如果进程太多看不过来,就加管道配合head或者用pgrep直接搜关键词拿PID。
进程找到了,接下来就是怎么处理的问题。kill -9是我最不推荐的姿势,它等于强制断电,进程没有机会做清理工作,可能留下脏数据或者没写完的文件。正确的顺序是先kill -TERM,让进程自己处理收尾工作,如果它不响应再考虑升级信号。还有kill -9在容器里有个大坑:在Docker容器里,你kill -9 PID 1的时候不一定能杀掉容器,因为PID 1有特殊处理,可能直接让容器退出或者忽略信号,具体表现要看镜像的entrypoint怎么写的。
定位性能问题的时候,top里的PID加上top -Hp可以看线程级别的CPU占用,如果发现某个线程一直占满CPU,用printf '%x\n'把线程号转成十六进制,去jstack或者gdb里查就能定位到具体是哪个业务逻辑在死循环。这套组合拳在排查Java应用CPU飚高的时候特别好用。
2.3 日志排查不完全等于tail -f
看日志是日常操作,但很多人只知道tail -f一个用法。tail -f确实适合实时跟踪,比如发布后盯着看有没有报错。但排查过去某一时刻的问题时,更常用的是tail -n 100加上grep过滤关键字,比如tail -n 1000 app.log | grep "ERROR"看最近一千行里有哪些错误。再老练一点的做法是结合时间窗口,用sed -n '/2025-01-15 14:30/,/2025-01-15 14:35/p'把某个时间段内的日志全部捞出来,不用肉眼去翻整个文件。
systemd系统的话,journalctl是比直接看文件更省事的工具。journalctl -u nginx --since today就是看今天nginx服务的日志,加上-p err只看错误级别。有次排查一个服务间歇性重启的问题,直接看应用日志什么都没发现,用journalctl -u myservice -f一看,发现是OOM Killer在作案,因为日志级别不高于某条线根本不会写进应用日志里,而systemd的日志是全量的。这个思路很重要:应用日志只是冰山一角,系统层的事件要去看journalctl或者dmesg。
3. 文件操作里最危险和最常用的那些命令
3.1 删除文件:rm命令的教训与正确用法
rm -rf是Linux里最容易出事的命令,没有之一。它危险在几个组合:-r递归、-f强制不提示、以及通配符的误展开。我最刻骨铭心的一次是打算清空backup目录下不要的旧包,打了个rm -rf backup/,结果因为前面少了一个空格,bash把backup和当成两个路径展开,实际上执行了rm -rf backup *——整个目录下的所有东西都没了,包括正在用的代码。
后来我给自己立了几条规矩:一,能用find -delete的地方不用rm -rf,至少能看到删的是什么;二,变量路径必须先echo检查再删;三,涉及删除操作前先看一眼pwd。还有一个更保险的习惯是:删除之前先ls看一眼展开后的通配符结果。比如想删所有.log文件,先ls *.log看看会匹配到哪些文案,再执行删除,这多花三秒钟可以避免很多悲剧。
那能不能删错了恢复?如果是普通文件,可以试试extundelete或者testdisk,但前提是删除后立刻停止写入,而且成功率不高。生产环境最靠谱的防线还是备份——重要数据做快照和异地备份,rm能删掉文件但删不掉备份。再有就是养成用mv代替rm的习惯,先mv到一个临时目录,确认没问题再清空。
3.2 查找文件:find命令的关键组合
find的选项看起来多,但日常核心用法我没记超过五条。最常用的是find /data -name "*.log" -mtime +7,按名字、按修改时间过滤。-mtime +7表示7天之前的文件,-mtime -1表示一天以内的,这两个在处理日志清理时经常配合使用。找到之后加上-exec ls -lh {} ;查看大小,或者配合-delete直接删除,省得先find再xargs那一长串。
比find更高效的是locate,它基于数据库查询所以快得多,但有个致命缺点:数据库不是实时更新的,刚创建的文件locate查不到,还得updatedb刷新。所以我只在找系统库文件这类长期不变的东西时用locate,业务环境里一律find,避免拿到过期的结果。
3.3 文本处理三兄弟:grep、sed、awk
grep是日常最常用的命令了,但还是那句话,会用和用得好差别很大。grep -r递归搜目录,grep -n显示行号,grep -i忽略大小写,grep -v反向匹配,这些都是基础。高级一点的用法是grep -E支持正则,比如grep -E "ERROR|Exception"同时捞两种错误。还有grep -A 5 -B 5在匹配到的行前后各显示五行,这个在翻日志时特别好用,能顺带看到报错前后的上下文。
sed最核心的两个用法是替换和行操作。sed 's/old/new/g'做文本替换,注意-i参数才是真正写回文件,不加-i只是输出到屏幕,很多人第一次用的时候忘了加-i导致白干。sed -i 's/old/new/g' file直接改文件,但Mac上的sed语法和Linux不完全一样,Mac需要sed -i '' 's/old/new/g',多一个空引号参数。这个问题我踩过好多次,每次换电脑都要重新想一遍。
awk是处理结构化文本的神器,但不用学太深。awk '{print $1, $3}'按空格或制表符拆分列,awk -F ','指定逗号分隔符,awk '{sum += $1} END {print sum}'做简单统计。特别是日志分析的时候,像awk '{print $4}' access.log | sort | uniq -c排序统计IP访问次数,或者awk '{print $NF}'按最后一个字段提取状态码,这些组合能省掉一堆手动统计的时间。
4. 网络排查:从ping到端口连通性,一条线讲清楚
4.1 网络问题排查的正确顺序
网络问题的排查不能靠瞎猜,要一层一层剥。我的顺序是:先确认本机状态——网卡有没有起来、IP对不对、默认路由通不通;然后确认目标主机通不通——用ping测ICMP;再确认目标端口通不通——用telnet或nc;最后才是看协议层的东西——用curl测HTTP、用dig查DNS、用traceroute看路径。每一层的结果都决定了下一步的方向。
比如用户反馈“网站打不开”,接到这种工单我不会直接去ping网关,而是先在本机跑ip addr和route -n确认网络配置正常,然后ping一下网关地址,通了说明局域网没问题,再ping目标服务器外网地址,通不了就查路由器或者防火墙。这个过程是收敛式的,每一步都在缩小排查范围,比你直接在应用层瞎猜要有用得多。
4.2 ping命令:活着不等于能用
ping是最直观的网络测试工具,它的原理就是发送ICMP Echo请求,对方回一个Echo Reply。用法上我们最常用的两种:ping ip测试目标是否可达,ping -c 4指定发几个包而不是无限ping下去。ping的通和延迟低只说明ICMP层面的连通性没有太大问题,但完全不代表服务正常。很多网络策略会放行ICMP,却不放行业务端口,所以ping通之后发现网站还是访问不了,这种情况太常见了。
ping还有一个容易忽略的指标:丢包率。ping -c 100的丢包率如果持续超过1%,就该怀疑链路质量了,尤其是在跨运营商或者跨国链路上。稳定性比单个延迟数字更重要,延迟偶发的高可以接受,但丢包率高就说明网络传输有问题,要么链路拥塞,要么有设备防火墙在丢包。局域网内ping丢包通常指向网线、交换机端口或者网卡驱动有问题,可以逐个排查。
4.3 端口连通性:telnet、nc和curl的区别
很多天跟telnet相关的热词,其实telnet这个工具本身有两种用法。一种是连上远程主机的23端口做终端会话,这属于老古董用法了;另一种是测试某个IP的某个端口是否开放,这也是运维排查中最常用的场景。判断逻辑很简单——telnet ip port,如果进入了一个连接成功的黑窗口或者显示Escape character,说明端口通;如果报Connection refused或者connect timed out,说明端口不通或被防火墙挡了。
telnet能测TCP端口,但有一些场景它不够用。比如怀疑端口通了但协议不对,更专业的工具是nc。nc是在排查和脚本里更好用的工具,nc -zv ip port一次测试多个端口,-z表示只探测不发送数据,-v显示详细信息。这个命令常常一行能测完几个端口,省去多次telnet。也可以用echo > /dev/tcp/ip/port这种bash内建的方式在脚本里快速判断,写监控脚本的时候特别好用。
测HTTP服务能不能用就用curl。curl -I直接返回响应头,curl -v可以看到完整握手过程和TLS证书信息,curl -k跳过证书验证。调试接口时curl -H加自定义Header,curl -d发POST请求,配合-j把cookie存下来。可以说curl就是开发调试接口的瑞士军刀,网络四层测完协议之后,七层的验证全靠curl。忘记带密码连接数据库的检查也可以这样套:先说telnet测端口,再用curl测业务的健康检查接口,两步就能定位服务是不是真的可用。
4.4 配置与防火墙:看一眼就懂的排查命令
服务器不通的另一种常见原因是防火墙配置问题。Linux下有iptables和firewalld两套体系,新版系统基本都用firewalld。排查的时候先iptables -L -n看规则,注意-n参数是不反解域名,否则可能因为DNS解析慢卡住。如果有firewalld,firewall-cmd --list-all查看当前配置,firewall-cmd --add-port=8080/tcp --permanent加端口规则后还需要firewall-cmd --reload重载,这个步骤经常有人忘。
华为等网络设备上的防火墙配置命令稍微不太一样,思路是一样的,找ACL和域间策略。很多网络问题都是策略放行顺序不对,尤其是默认deny策略放在放行策略前面的时候,后面的放行规则根本不会生效。排这种问题的时候,先看设备上有没有显式的deny规则,再确认放行规则的顺序和匹配条件,很多时候问题不在配置对不对,而在配置顺序。
5. Git日常操作备忘:别让版本库变成后悔药仓库
5.1 高频动作:状态、提交、推送、拉取
Git命令热词里最高的就是git status、git add、git commit、git push这套日常循环。这里面有个习惯问题:提交之前一定要先看git diff确认改了什么,而不是盲目git add .一把梭。有一次我改了一个配置文件想提交,结果顺手把本地的密钥文件也git add进去了,差点推到远程仓库。从那以后我养成了规矩:git add之后必须git status看一眼,确认暂存区里没有不该提交的东西。
git commit的message也值得注意,规范一点写清楚“做了什么改动、为什么这么改”,方便后面回溯和同事review。一句话commit message不是不能用,但到排查问题的时候你会感谢自己当时写清楚了。另外,养成小步提交的习惯,一次提交一个逻辑改动,而不是攒了三天改动一次性提交,否则出了问题很难精确回退。
5.2 分支操作:创建、切换、合并
分支相关的命令就那几个,git branch -a列出所有分支,git checkout -b newbranch从当前分支创建并切换,git merge和git rebase的区别是面试常考也是实操常踩坑的点。我的建议是,团队协作中尽量用merge,虽然提交历史会出现分叉,但保留了真实的时间线;rebase会让历史变成一条直线,看起来干净但修改了提交ID,一旦推送到远程再rebase,会造成其他人的仓库出问题。rebase适合自己本地整理提交记录,别拿去动已经push的分支。
合并的时候冲突是绕不开的。看到“CONFLICT”不要慌,冲突其实是git在帮你做卫生——它不敢乱动你的代码,只把冲突标记出来让你自己决定。处理流程就是打开冲突文件找<<<<<<< HEAD和>>>>>>>标记之间的内容,一段一段确认要保留哪边,然后git add标记为已解决,再git commit完成合并。
5.3 撤销与回退:最容易翻车的点
撤销这部分坑最深。git checkout -- file是丢弃工作区的修改,git reset HEAD file是把文件从暂存区移出来但保留修改,git reset --hard HEAD是彻底回退到最近一次提交并且丢弃所有工作区修改。第三个命令非常危险,因为丢弃的修改无法找回,没有后悔药。
git reset --hard配合commit id可以回退到任意历史版本,但同样会丢掉之后的提交记录。如果你已经push到远程了,回退之后需要git push --force才能强制覆盖远程,这是极度危险的操作,会影响到所有拉过这个分支的同事。我的建议是,远程分支需要回退时,优先用git revert反做一次提交,而不是reset——revert生成一个相反的提交,历史是向前走的,别人pull的时候不会有任何冲突。至于reset,留给本地还没push的提交去用就好。
6. 服务与应用运维:systemd、Docker、Redis
6.1 systemctl日常三件套:start、restart、status
Systemd管理服务的命令其实就那几个:systemctl start/stop/restart/status,加enable设置开机自启。运维上最常用的判断逻辑是systemctl status不只看服务是不是active,看子状态是running还是exited,还要看具体的日志和进程信息。有一次同事说服务挂了,systemctl status显示的其实还是active,因为主进程fork了子进程之后自己没有退出,服务处于瘫痪但状态正常的状态,这就是为什么不能只看状态栏的原因。
服务异常时journalctl -u 服务名 -n 50看最近日志,这个组合比翻/var/log/messages高效得多。修改配置文件之后必须systemctl daemon-reload再restart,有时候改了配置忘了reload,restart之后还是旧配置,这事我踩过两三次了。还有一个经验是别在服务运行的目录下改配置,有些服务会定时重新加载配置文件,你改了还没保存,它可能就把你的修改覆盖了。
6.2 Docker容器操作:进入容器与看日志的正确方式
容器时代的命令也是必考科目。docker ps看运行中的容器,加-a看全部,docker images看镜像。查容器状态时docker stats比top更直观,能一次性看到所有容器的CPU和内存使用率。
进入容器的命令阵这里有个大坑。docker attach是很多人用错的地方——attach进去之后,如果直接按Ctrl+C退出,这个健盘操作会传给容器主进程,相当于向主进程发送SIGINT信号,很可能导致容器直接退出。正确进容器的姿势是docker exec -it container /bin/sh或者/bin/bash,exec是开启一个独立的shell进程,退出不会影响容器主进程。可以记一条经验:能不用attach就不用attach,除非你明确知道自己要在主进程的终端里操作。
看容器日志用docker logs container,加-f跟踪,加--tail 20只看最近二十行。这套参数几乎和tail -f一样。还有一个排查技巧:容器起不来的时候,docker logs看不到日志的话,先docker inspect看看挂载卷和启动命令是否正常,再docker start之后立刻docker logs -f看启动过程报了什么错。
6.3 redis-cli常用命令:生产环境别犯低级错误
Redis虽然是一个内存数据库,日常运维中也用得上命令行工具。连上Redis之后,最常用的也就那么几条:ping测连通,info看内存和连接数,dbsize看key数量,keys *看key列表——这句在生产环境要慎用,keys *会阻塞Redis进程,替代方案是用scan做迭代遍历。缓存故障的排查思路通常是redis-cli info memory看内存使用,mem_fragmentation_ratio超过1.5就该关注碎片率。缓存key过期集中导致的雪崩,可以用EXPIRE加上随机过期时间缓解,这个在开发阶段就应该想到。
7. Windows环境:系统维护与脚本排查
7.1 网络与磁盘检查:ping、ipconfig、chkdsk对应关系
虽然服务器大多跑Linux,但平时总免不了用Windows环境干活。Windows下的命令和Linux不少是名字相同但功能有差异的。ping基本一致,ipconfig对应Linux的ifconfig或ip addr,route print对应route -n。排查网络问题时思路完全一样,先确认本机配置,再测试连通性,从ipconfig里找IPv4地址和默认网关,然后ping网关。
chkdsk这个命令在Windows下是个狠角色,它用于检查磁盘文件系统错误。热词里有人问“chkdsk命令出现将检查该卷是否存在坏扇区是什么意思”,这个提示的意思是:磁盘检查要开始了,过程中会扫描有没有物理坏道。运行chkdsk一般需要管理员权限,C盘通常还会提示重启后执行,因为它要占用正在使用的磁盘。跑chkdsk前最好先备份重要数据,有时候它发现的不仅仅是坏扇区,还会尝试修复目录和文件索引,修复过程可能比较慢,不要中途强制关机。
7.2 C盘清理和脚本闪退的排查
C盘空间不够是Windows用户永恒的痛。先df -h对应的思路是看C盘还剩多少,再对症下药。清理C盘的命令其实绕不开清理临时文件:cleanmgr /sageset调出磁盘清理配置,或者直接用系统自带的存储感知自动清理。命令行层面好用的是一个PowerShell命令,删除临时目录的内容,不过要注意权限和进程占用。最值得清的是C:\Users下AppData\Local\Temp目录,还有一个被忽略的大户是Windows更新缓存,可以用Dism命令清理。
还有热词里提到的Windows脚本闪退问题。双击一个bat脚本,窗口刷一下就没了,根本看不到报错。解决方法是先不用双击,打开cmd,然后手动敲脚本路径执行,这样窗口会停在报错信息那里;或者干脆在.bat文件末尾加pause指令,执行完等用户按键,这样能看到输出。闪退最常见的原因是脚本里引用了不存在的命令或路径,还有中文路径和空格没有加引号导致解析错误。用set var=value的时候,=两边别加空格,否则空格会被当成值的一部分。
7.3 cmd和PowerShell,选谁以及基础命令对应
Windows下除了cmd,还有PowerShell这个大杀器。新手容易在两者之间反复横跳。简单说,写简单脚本用cmd的.bat就行,涉及系统管理、文件批量处理直接上PowerShell。PowerShell的命令风格很怪,看起来像函数名,比如Get-Process,Get-Service,但入门之后效率非常高。快速转换:cmd里netstat -an对应PowerShell里Get-NetTCPConnection,ipconfig对应Get-NetIPConfiguration。记住关键词,需要用的时候能想到有这些命令,再去查具体语法,比死记快很多。
8. 多媒体处理与Shell自动化细节:ffmpeg和脚本的坑
8.1 ffmpeg:转码和处理音视频的实用命令
ffmpeg在视频处理和自动化运维里是真神器。最简单的转码命令ffmpeg -i input.mp4 output.avi就能完成转封装,压缩视频用ffmpeg -i input.mp4 -crf 23 output.mp4,crf值越小画质越好文件越大,一般用23到28之间。截取片段用-ss指定开始时间、-t指定时长,提取音频用-map 0:a,动图截图用-f gif。处理图片也顺手,ffmpeg -i input.jpg -vf scale=800:-1 output.jpg按宽度等比缩放。
ffmpeg最大的坑是参数顺序和编码器选择。你把输出文件写在了输入前面会报错,不指定编码器时会自动选一个默认的,结果可能不是你想的h264而是别的。还有处理大文件时,没有加-c copy会重新编码,速度慢且画质损失。只是改封装格式、不转编码的时候用-c copy速度极快,这是省时省力的关键。
8.2 Shell脚本细节:shift、变量引用和脚本稳定性
Shell自动化这块热词里有shift命令。shift的作用是把位置参数左移一位,比如脚本里执行了shift之后,$2就变成了$1。在循环里处理参数列表时非常常用,比如while [ $# -gt 0 ]; do case $1 in ... esac; shift; done这种经典的模式就是挨个吃掉命令行参数直到没有为止。很多工具的内部实现就是靠这个来解析不同参数选项。
Shell脚本的稳定性还取决于引号的正确使用。变量不加引号是个大坑,比如for file in $files,如果file里包含空格,这里就会被拆分成多个值,导致处理错文件。凡是变量出现在命令行里,几乎都应该用双引号包住,比如ls "$file",而不是ls $file。这个细节对新手来说是隐形炸弹,尤其是文件名带空格的场景,不加引号一定会出问题。
还有脚本闪退的问题其实在bash里也一样常见——报错没有立即退出。默认情况下bash碰到错误命令不会自动停,会让脚本继续跑,很容易连锁出错。建议在脚本开头加set -eu,-e表示出错就退出,-u表示变量未定义就报错。加上之后很多潜在问题在第一时间暴露,脚本也就不容易做出奇怪的举动了。
9. 事故与避坑记录:我替你们踩过的坑
9.1 高危命令速查表
这个表我放在备忘的最前面,提醒自己哪些命令在日常下要格外小心:
| 高危命令/操作 | 有什么坑 | 替代方案 |
|---|---|---|
| rm -rf | 通配符展开、路径写错都会导致误删 | 删除前先ls确认,用mv代替,find -delete |
| git reset --hard | 丢弃工作区所有修改无法恢复 | 本地可用,慎用,远端用git revert |
| docker attach | 退出时会带崩容器主进程 | 用docker exec进入 |
| chkdsk /f | 扫描修复慢,可能影响正在用的磁盘 | 休息时段跑,备份数据 |
| kill -9 | 不让进程做清理,可能产生脏数据 | 先kill -TERM让进程自己收尾(再说一遍) |
| sed -i 在Mac上 | 语法不同会报错或生成备份文件 | 统一用Linux或加空参数 |
9.2 几个真实翻车案例
我分享几个真实的翻车现场,比任何命令文档都更能说明问题。
第一个就是前面说过的rm -rf少打空格删库事件。当时失手删完之后我的反应不是马上重启机器,而是第一时间把磁盘挂到只读状态,然后用文件恢复工具尝试抢救,顺便检查有没有远程备份。最后是靠前一天晚上的备份恢复了主要数据,但当天下午的几个文件丢了。这个事的教训是:备份永远比事后恢复重要,运维人员的安全感来自备份而不是操作水平。
第二个是docker attach的案例。我进入一个跑了三天的重要容器改配置,完事之后习惯性按了Ctrl+C想退出,结果容器直接停了,当时我就意识到这个问题。后来发现重启进程还好数据没问题,但从此以后我就只进docker exec,再也不attach了。容器主进程一旦中断,它的退出会影响整个容器内的所有服务,这个连带效应很容易被忽略。
第三个案例是关于telnet的误判。有次排查一个跨网段的服务不通,telnet IP 端口的输出一直是command not found——这是在Windows环境上telnet客户端没装,跟网络没半点关系。Windows默认不装telnet客户端,用之前要在程序和功能里开启,或者直接在命令行里用powershell的Test-NetConnection ip -Port port,效果一样还不用装telnet。这个案例提醒我:排查工具本身的可用性也是一种前置条件。
9.3 历史命令与操作审计的一些建议
最后提一下history命令。history看历史命令是基本的,但很多人不知道history的默认记录数有限(默认1000条),而且多个终端的记录会互相覆盖。更实用的做法是修改HISTSIZE和HISTFILESIZE,再设置HISTTIMEFORMAT="%F %T "让每条记录都带上时间戳,这样排查问题的时候能知道当时谁在哪台机器上执行了什么命令。另外用Ctrl+R反查历史命令比重新打一遍快太多了,我现在写命令记不住的时候都是下意识按Ctrl+R搜索。
顺着这个思路,公司服务器上建议开启操作审计,比如记录所有用户执行的命令到日志文件。工作中我常和实践证明的做事逻辑一样——一开始别想着一步到位把命令体系搭完整,而是遇到一个问题记一条,随手补充,一个月下来你的备忘就变成了一个非常有个人特色的工具库。
我个人在实际操作中的体会是:记忆命令最好的方式不是背诵,而是带着问题去用。端口不通的时候去查telnet怎么用,磁盘满了去查怎么清理,每次都记一点,用两三次就忘不掉了。这份备忘也一样,不需要全部看完,收藏起来用到再翻,时间久了哪些命令能解决哪些问题,你心里自然有数。我还会继续往里补充踩坑记录和新的命令组合,也希望你自己动手整理一份专属的版本——别人的备忘永远是参考,自己攒出来的才是真正长在手上的功夫。