
前阵子接手一个隔壁组留下的业务模块第一天光是查日志、批量改配置、翻 Git 历史就花了我大半天。有些命令我记得大概可真要写的时候脑子里全是参数是 -l 还是 -a这类拉扯。那天晚上我做了个决定与其零散地搜不如把手头工作常用命令整理成一份自己的备忘。这份备忘后来救了我很多次也让我意识到一个事——工作里真正要的不是背全命令而是知道按什么思路查、怎么把一条命令拧成一套动作。这篇文章聊聊我现在终端里的常用命令清单以及我怎样维护这份清单。如果你是刚入行的开发、运维或者是每天要跟服务器打交道的测试、数据同学可以照着这份内容搭一套自己的命令备忘。1. 为什么命令备忘比死记硬背更靠谱1.1 大脑是用来思考的不是用来背参数的我见过不少同事桌上贴满便利贴全是tar -zcvf 打包、chmod 777 改权限这类小抄。贴了很好但问题是便利贴只会越贴越多最后连自己都找不到哪张是哪张。命令这东西有个特点量大、参数多、版本差异大而且很多命令你一个月才用一次。一个月用一次的命令正常人都会忘忘了靠搜也没错错的是每次都从头搜、每次都记不住。我的观点是把命令从记忆负担里摘出去变成一个可检索、可更新的外部索引。大脑只负责一件事——记住我整理过一份备忘遇到 XX 问题去里面查。这样既不会因为忘了参数而卡住也不会因为东搜西搜而打断心流。我用的工具很简单一个纯文本的 markdown 文件放在个人笔记目录里跨设备同步。为什么不用在线文档或者 IDE 里的插件因为我需要它轻、快、离线可用不想为了查一条命令还打开一个几百 MB 的编辑器。终端里一条grep能查到的内容绝不动用一个重型应用这是我维护备忘的第一原则。1.2 整理备忘的三条原则如果你打算今天就开始整理自己的命令备忘我强烈建议每条记录都遵循下面三条按场景分组不按命令排序。不要写ls 命令详解、grep 命令详解要写查看端口被谁占用、统计日志中某个错误出现的次数。因为人遇到问题是从场景出发的不是从命令出发的。每条命令写一句为什么用它。记录lsof -i:8080的时候旁边标注端口占用排查优先用这个比 netstat 直观能直接看到 PID。这句备注才是备忘里最值钱的部分。把踩过的坑写在下面。比如find . -name *.log -exec rm {} \;一定要加{}和\;漏了就会报错。这种坑自己踩过一次就会长记性但记在文档里能帮你省掉第二次踩坑。举个我备忘里的真实条目# 场景端口被占用查是谁在监听 lsof -i:8080 # 为什么直接显示进程 PID 和命令名不用再拿着 ss/netstat 结果二次加工 # 坑某些系统没有 lsof先 yum/apt install; macOS 自带这样一条记录比在 Stack Overflow 存书签好用得多。书签是别人的回答备忘是你自己的判断。1.3 文档式记忆和场景索引式记忆的差别我拿自己电脑里的两份笔记做过对比。第一份是按命令字母序写的命令大全第二份是按工作场景写的排查手册。同样是查磁盘为什么满第一份我得先去目录里找磁盘相关章节然后里面列了 df、du、find 十几条每条的语法都写全但我不知道先敲哪个第二份则是直接写了一个五行的排查流程从 df 定位分区、到 du 找大目录、再到 find 找超大文件我照着敲一遍问题基本就解决了。差别在哪第一份是字典第二份是菜谱。字典有用但工作的时候你需要的是菜谱。所以我现在维护的备忘本质上是一个个微型排查流程的合集。命令仍然是主角但组织方式完全围绕我此刻要解决什么问题。2. 工作台前的高频命令文件和磁盘操作自查2.1 一条磁盘满了的排查链df、du、find 怎么配合机器磁盘告警算是运维侧最常见的故障之一但不少人一上来就find / -type f硬扫扫半天也没结果。我习惯用一条链路往下逐层缩小范围。第一步看整体df -hdf -h用人类可读的单位列出所有挂载点的使用率。哪块分区满了一眼就能看到。注意这里有个细节很多云服务器会挂载多个数据盘日志应用一般都写在最大的数据盘上别盯着系统盘看半天。看到使用率最高的分区之后第二步进去定位大目录du -h --max-depth1 /var/log 2/dev/null | sort -hr | head -20du的--max-depth参数控制只统计一层子目录避免输出爆炸sort -hr按人类可读大小反向排序这样最大的目录直接排在最上面。第三步如果在某个目录里发现一堆巨型文件用 find 按大小筛find /var/log -type f -size 100M -exec ls -lh {} \;这条命令的意义在于把扫所有文件变成只扫大于 100M 的文件速度差出一两个数量级。整个过程三步走每一步都比上一步更聚焦这是经典的排查递进思路。2.2 批量操作多文件find exec 和 xargs 的取舍批量操作文件是命令备忘里的重头戏。find定位到目标文件之后要把结果交给下一条命令处理两个常见方式就是-exec和xargs。-exec 适合写起来直观、文件数量不太多的场景比如把近期修改过的配置文件全部复制到一个备份目录find /opt/app/config -name *.conf -mtime -7 -exec cp {} /tmp/config_backup/ \;这里分号\;是必须的表示每条结果执行一次命令。{}是当前文件的占位符。忘了写\;或者没有加引号shell 会直接报语法错误。xargs 适合处理大批量文件性能更好因为它会分批把多个文件名传给下游命令而不是一个文件启动一次进程find /opt/app/logs -name *.log -mtime 30 | xargs rm -f上面这条就是找到 30 天前的日志文件并删除的经典写法。有一点要提醒文件名如果包含空格直接管道给 xargs 会被拆开应该加-0参数配合find -print0find /opt/app/logs -name *.log -mtime 30 -print0 | xargs -0 rm -f2.3 存量文件清理的安全感说到删除就得提一句安全意识。rm -rf是每个命令备忘里必须标红的内容。我的原则是删除操作前先看一眼find的输出确认范围实在不放心就改成mv到临时目录观察几天没问题再真删。find /data/logs -name *.log.gz -mtime 90 -exec mv {} /data/temp_delete/ \;把删除变成移动成本几乎为零但安全感提升一个量级。这条习惯帮我避免过至少三次误删事故其中一次是把应用正在写的日志目录给挪走了还好只是占用了磁盘没造成数据丢失。现在团队里所有清理脚本我都要求先 mv 后删。3. 日志与排错你得先知道现场在哪3.1 别用 vi 打开大日志tail 和 less 才是正道很多刚工作的人看日志的第一反应是vi app.log然后整个终端卡死。这个问题在于vi 会把整个文件加载到内存而线上日志动不动几个 GB。正确姿势是tail和less配合使用。实时跟踪新写入的日志tail -f /opt/app/logs/app.log-f是 follow持续输出文件末尾新增内容。在追查线上问题的时候我基本上都会开一个独立的终端窗口跑这条命令然后去复现问题日志就会一行行滚出来。如果日志太吵加个grep过滤tail -f app.log | grep --line-buffered ERROR--line-buffered确保 grep 一行行实时输出而不是等到攒满缓冲区才打印这个参数不加的话会感觉日志卡住不动。不实时跟踪但文件又大想翻页阅读用 lessless -N app.log-N显示行号方便后面定位。进入 less 之后按/关键字搜索按n跳到下一个匹配项按ShiftG跳到文件末尾按g回到开头。这套键位记熟大日志文件浏览效率翻倍。3.2 用 sed、grep、awk 抽取切片而不是打开文件人眼找文件日志太大或者只想看某段时间的报错我通常不把文件拖进 IDE而是直接用命令切片段。sed 按行号区间切sed -n 1200,1250p app.log只看第 1200 到 1250 行的内容。-n表示安静模式不让 sed 把没匹配的行也打印出来。适合你已经从某条报错里看到了行号想取上下文的情况。grep 按关键字找上下文grep -n -A 5 -B 5 NullPointerException app.log-A 5显示匹配行后面 5 行-B 5显示前面 5 行。查异常堆栈时光看报错那行没用得看调用链这个参数比单纯grep Exception有用得多。awk 按时间范围切awk $0 2025-03-18 14:30:00 $0 2025-03-18 15:00:00 {print $0} app.log前提是日志每行以时间戳开头。这个写法简单直接把半小时内的请求全部抽出来再配合后面的统计命令处理。3.3 一次真实的排错过程从日志到定位依赖服务去年我处理过一次比较典型的接口超时问题完全靠日志命令一步步缩小范围。用户反馈某个报表接口偶尔会卡 10 秒以上我先把日志拉出来看这一小时的请求grep reportApi app.log | awk $0 14:00 $0 15:00结果发现超时请求都集中在一个数据源实例上。继续查这个请求内部有没有调用第三方服务失败把日志里对应的 traceId 抽出来grep traceId_abc123 app.log然后用grep -A 20看了整段调用链。很快发现核心问题不在应用本身而在依赖的缓存服务连接池饿死了所有请求都在等连接。最后处理的不是改业务代码而是去调高缓存服务的连接池上限并给应用侧加了熔断。这个案例没什么高深命令但流程值得记进备忘先按时间切片缩小范围再按关键字抽取上下文最后沿着调用链找到根因。这套流程写在你的备忘里比记一百条孤立的命令都有用。4. Git 命令备忘别让撤销成为心理负担4.1 日常场景速查表Git 命令条款太多但工作中反复用到的就那么几个。我把自己最常用的整理成一张表放在备忘开头保证一分钟内能找到场景命令当前分支状态git status -sb最近 10 条提交记录含分支图git log --oneline --graph -10拉取最新代码并保持工作区整洁git pull --rebase暂存当前修改切换分支git stash push -m 说明回来用git stash pop撤销已 add 的文件git restore --staged 文件名撤销工作区的修改git restore 文件名不小心删错分支git reflog找到提交号git branch 分支名 提交号提交后想改提交信息git commit --amend这里特别想说git pull --rebase。我很少用git pull默认的 merge 方式因为多个协作者往同一个分支推代码merge 会带来一堆 Merge branch 的提交记录历史图非常乱。rebase 会把本地提交搬到远程提交之后让历史保持线性。它确实可能有冲突要处理但冲突处理后整个提交历史清爽得多。对多人协作较频繁的项目这一条能明显减少历史图没法看的焦虑。4.2 误操作自救reflog、reset、amend 的边界Git 最让人惶恐的是删错了怎么办其实绝大多数误操作都有的救核心就是git reflog。它记录了 HEAD 指针的每一次变动相当于 Git 的操作流水账。git reflog输出里每一行左边是一串提交号的简写右边是执行的命令。想回到某个节点直接git reset --hard 提交号这个--hard是双刃剑它会把你工作区、暂存区的改动全部覆盖成指定提交的状态。如果你只是想把分支移到某次提交、但保留当前目录的修改应该用git reset --soft。我一直的提醒是reset 之前先git stash或复制一份当前目录的 diff不然回不来了别怪我没说。git commit --amend适合提交完发现自己词不达意的情况。它会把本次提交和上一次提交合并成一个新提交同时重写提交信息。特别注意amend 会改变提交 hash如果这个分支已经推送过且别的同事也在用amend 会造成历史分叉一般情况下只对还没推送的本地提交用。4.3 能少打字就少打字status、log、diff 的精简用法我很少用git status默认输出因为信息太冗。git status -sb一行就够-s是简短模式-b显示分支跟踪状态。git status -sb看到结果形如## main...origin/main [ahead 2]就知道自己有两条提交还没推所有改动文件按字母序排在后面。想快速看这次改了哪些文件但不看内容git diff --stat想追一个文件在最新两条提交里的具体变化git log -p -2 -- src/utils/api.ts这套组合比我用 GUI 工具看得还快。我现在基本不开图形化 Git 客户端所有操作都在终端里靠这十几个命令完成原因无他快且不用离开键盘。5. 把零散命令变成自己的手册别名、函数与检索5.1 用 alias 固化高频命令有些命令不是记不住而是太长。我把最长用的几个写进 shell 配置文件一劳永逸alias ..cd .. alias llls -alFh alias gsgit status -sb alias glgit log --oneline --graph -10 alias gcgit checkout alias tftail -f有人问这样会不会让自己更不会命令我的看法是alias 是把记忆负担转交给配置文件而不是逃避学习。真到了没有 alias 的机器上git status -sb也就比我多敲四个字母。但日常工作里省下的输入时间积少成多。5.2 用 shell 函数封装套路型命令alias 只能做简单替换遇到先跑 A 再跑 B 还要拼接参数的套路就要用函数。我的~/.bashrc里常驻几个自制函数。第一个是查端口占用port() { lsof -i:$1 | grep LISTEN }用法是port 8080立刻显示监听 8080 端口的进程。没有函数的时候是lsof -i:8080 | grep LISTEN多敲十来个字符但关键是每次都要想起加grep LISTEN这一步很容易忘。第二个是打包并排除 node_modulestargz() { tar -zcvf $1.tar.gz --excludenode_modules --exclude.git $1 }用targz myproject就能把整个项目打包自动排除最占体积的两类目录。这个函数是从一次打包后压缩包 400MB、解压出来没用的经历里总结出来的。5.3 快速检索历史命令别再用方向键翻在终端里找之前执行过的命令大多数人会用方向键一次一次往上翻效率很低。我常用方式是CtrlR反向搜索输入关键字匹配到再按回车但如果你想看某天执行过哪些跟 git 有关的操作用 history 管道加 grep 更快history | grep git stash如果有很多次操作可以用!行号直接重跑某条历史命令省得再敲一遍。5.4 我是怎么维护这份记忆外置的备忘录的维护节奏我建议是随踩随记。每踩一个坑、学到一条好命令当场追加到备忘文件里不攒、不拖。我自己的维护流程有三个固定动作每周五花五分钟扫一遍 history看到一周里重复执行过两次以上的命令组合就判断有没有固化成 alias 或函数。每次项目恢复接手旧模块时把排查过程里用到的新命令按场景补进去。每半年重新整理一次分组删除已经完全不再用的条目避免备忘膨胀到搜不出来。这个习惯坚持下来你的备忘会越来越贴合自己手头的工作。别人的命令清单只能当参考只有记录了自己决策过程和踩坑经历的备忘才是真正能救命的工具。6. 从单条命令到组合拳我沉淀的三个模板6.1 发布前环境检查模板每次发版前我都要确认服务器环境正常。以前是一句一句敲后来我把检查项写成一个脚本模板发版前跑一遍心里就有底# 1. 磁盘使用率 df -h | grep -vE Filesystem|tmpfs # 2. 关键进程 ps aux | grep -E java|python|node | grep -v grep # 3. 应用端口 ss -tlnp | grep -E :8080|:9090 # 4. 最近 10 行日志有无明显异常 tail -n 10 /opt/app/logs/app.log这四条命令覆盖了空间够不够、进程在不在、端口通不通、日志正常不正常。发布最大的风险往往不是代码问题而是环境被之前的人改过状态。跑一遍模板能在发版前提前暴露一半以上的低级事故。6.2 日志时段统计模板接口报警经常是某时段请求量下降或者某类错误突然变多我常用下面这个模板统计某个特征值在指定时间段的出现次数grep PaymentTimeout /opt/app/logs/app.log | awk $0 15:00:00 $0 15:30:00只看 count 的话在命令外层套| wc -lgrep PaymentTimeout app.log | awk $0 15:00:00 $0 15:30:00 | wc -l要按错误类型分组统计就把 grep 关键字换成接口路径配合awk {print $N} | sort | uniq -c | sort -nr。这个组合在线上问题复盘时几乎必用比人眼数日志可靠一个量级。6.3 定时清理加保底备份模板配合 crontab 做定时任务时我有一套先备份后清理的模板适合日志类文件的轮转场景# 每天凌晨 2 点执行 0 2 * * * find /data/logs -name *.log -mtime 7 -exec mv {} /data/backup/logs/ \; # 每周日凌晨 3 点删除备份目录中 30 天前的压缩文件 0 3 * * 0 find /data/backup/logs -name *.tar.gz -mtime 30 -exec rm -f {} \;这套模板的逻辑是7 天前的日志先挪到备份目录再留 30 天的缓冲期之后才真正删除。好处是即使线上问题在十几天后才被发现也能从备份里找回当时的日志。这类定时任务写入 crontab 之前一定先在终端手动跑一遍 find 加-exec echo {} \;看看选中哪些文件确认无误再替换成实际清理命令。最后分享一个我自己的小习惯命令备忘不是一次性写完的它是跟工作一起生长的。每次遇到一个这命令还能这么用的时刻就顺手补一行到对应场景下面顺手再删掉一条已经过时的记录。如果你觉得自己记不住命令别急着背先把自己手头三天内用过的命令拉出来捋一遍分个类每个场景留一条最顺手的剩下的都交给备忘文件。真正上了生产环境你会庆幸自己提前做了这件事。