很多人刚开始接触 Linux 的时候,最容易踩的坑就是把“常用命令”当成一份单词表来背。我也带过不少新人,最常被问的问题就是“这条命令怎么记不住”“参数太多怎么办”。其实命令这东西,靠背是背不下来的,真正能留下来的,是你在实际排查问题、处理数据、部署服务的过程里反复用出来的肌肉记忆。这篇内容我不会又整理一份ls、cd、pwd的字母表,而是想换一个思路——把 Linux 常用命令拆解成几个真实的工作场景,聊聊哪些命令在什么情况下真的能救你一把,以及它们背后的使用逻辑是什么。如果你正在从零学 Linux,或者已经会用一点但总觉得不够顺手,这篇内容应该能给你一些不一样的参考。
我的核心建议就一句话:不要问“这条命令是什么意思”,要问“我现在遇到的问题要用什么命令解决”。把命令挂到具体场景上,记忆负担会小很多,而且在面试、答辩、排查故障的时候,你能说出的不是零散命令,而是一套完整的处理链路。下面先把场景框架理清楚。
1. 为什么常用命令不是“背出来”的,而是按场景长出来的
1.1 先搞清楚命令是怎么分类的
Linux 里的命令看似多到吓人,但按作用可以粗略分几类:文件与目录操作、文本处理、进程与资源查看、权限与用户管理、网络排查、打包压缩与定时任务。绝大多数日常工作,翻来覆去用的也就是这些类目下的几十条命令。
我见过不少新手把apt install、yum install当成 Linux 的全部,装完软件就不知道下一步干嘛。其实安装软件只是开始,装完之后你怎么找到它的配置文件、怎么看它的日志、怎么确认端口起来了、进程占了多少内存、出问题怎么回滚——这些才真正决定你能不能扛住一台线上机器。
1.2 场景化的学习路径比索引式学习更有效
举个例子。你要排查一台 Web 服务器为什么响应变慢了,这一条排查链路里会用到top、free、df、ps、ss、tail、grep、awk这一串命令。你不需要单独背它们,因为当你有“排查慢”这个需求时,每一步都会自然牵出下一条命令。
反过来,如果你只是按字母序背awk的语法,背完三天就忘。所以我强烈建议把学习方式从“索引式”改成“任务式”:给自己设定一个小任务,比如“统计日志里访问量最高的十个 IP”,然后你会发现你需要cat、awk、sort、uniq、head,几个命令一条管道串下来,任务完成,命令也就记住了。
1.3 命令的“记忆锚点”是问题现场,不是语法书
这是我带人最深的体会。一个命令如果只在终端里跑过一次,没有任何上下文,它就是个过眼云烟。但如果这条命令解决过你一个问题,那它从此就留在你脑子里了。
比如我第一次用sed批量替换配置文件里的旧 IP 地址,是在一次迁移机房的凌晨,几百个配置文件要改。那次之后,sed -i我永远忘不掉,因为我知道它背后代表的是“一个人干完几百个文件的体力活”。所以不用焦虑为什么记不牢命令,多给自己制造点“问题现场”就行。
2. 文件与目录操作里被低估的三个基本功
2.1 ls 和 ls -l 的输出到底在告诉你什么
大家都会打ls,但很多人在ls -l的输出面前傻眼:drwxr-xr-x 2 root root 4096 Jan 1 12:00 data。这个字符串每个字段都有用,不是装饰品。
第一个字符d代表这是个目录,-代表普通文件;后面九个字符每三个一组,分别表示属主、属组、其他用户的权限;2是硬链接数;root root是属主和属组;4096是大小;后面是修改时间和文件名。排查权限问题时,第一件事就是盯这一行输出,比你在网上搜“permission denied”快得多。
我还经常用ls -lh看文件大小,h参数会把人眼难数的字节数转成K、M、G这种友好格式。线上排查磁盘占用的时候,这一条命令就够看出哪几个文件是大头。
2.2 find 和通配符的取舍:到底什么时候该用哪个
新手常犯一个错误:觉得find很复杂,所以动不动就用ls *.log这种通配符去匹配文件。通配符确实方便,但它有盲区——它只能匹配当前目录下的内容,而且对隐藏文件、权限受限目录无能为力。
find的强大在于你不仅仅能按文件名找,还能按大小、时间、类型、权限找。举个例子,我要找出/var/log下 7 天前修改过、大于 100M 的日志文件并删除,一条命令就能搞定:
find /var/log -type f -name "*.log" -mtime +7 -size +100M -exec rm {} \;注意这里的-exec,它是find的威力所在:找到的每一个文件都会作为参数传给后面的命令。用的时候先在不需要执行的地方把-exec换成-print预览一遍,确认名单没问题再真正执行删除。这是我吃了多少次亏之后养成的习惯——宁可慢一步,不糊里糊涂删文件。
2.3 du 和 df 的分工,很多人一开始就搞反了
df -h和du -sh都跟磁盘有关,但用途完全两样。df看的是文件系统的整体使用率,du看的是某个目录到底占了多少空间。
有一次机器报磁盘写满,我用df -h一看根分区 100%,但du -sh /一算,总量对不上。后来才发现是有个进程把一个已删除的大文件还在占用空间。此时df显示满的,du却找不出那个文件,因为文件在文件系统里已经被删掉,只是进程还握着文件句柄。这时候用lsof | grep deleted找到对应进程,处理完后磁盘才释放。
这种问题没有df和lsof配合,你会排查到怀疑人生。我的建议是:先df -h判断整体状况,再用du -sh逐层下钻定位目录,最后用lsof找残留句柄。
3. 文本处理三件套:grep、sed、awk 在真实工作里怎么用
3.1 grep 的几个高频参数和常见误区
grep是最常用的文本搜索命令,但大多数人只会grep "关键词" 文件。排查日志时,真正用得频繁的其实是这几个变体:
grep -v:反向匹配,排除某些行;grep -E:扩展正则,可以用|做多条件匹配;grep -c:统计匹配行数,而不是把每一行打出来;grep -r:递归搜索目录下所有文件;grep -l:只列出命中的文件名,不输出行内容。
比如我要在应用日志里找到所有报错行,并且排除掉已知的告警噪音,会写:
grep -E "ERROR|Exception" /var/log/app.log | grep -v "KnownNoise"有个误区要提醒一下:很多人习惯cat file | grep xxx,多了一个不必要的管道。grep本身就能接文件路径参数,直接grep xxx file性能更好,命令也更干净。能用重定向解决的事情,别用cat兜一圈。
3.2 sed 不只是“替换”,它的执行逻辑值得彻底搞清
sed最常用的功能确实是替换,命令长这样:
sed -i 's/old/new/g' config.conf但很多人不清楚s/old/new/g的各个部分各司其职:s表示替换操作,old是模式,new是替换后的内容,g表示全局替换,不加g只替换每行第一个匹配。
用sed批量操作时,我的建议是先用sed 's/old/new/g' config.conf看输出,确认没问题后再加-i写回文件。-i是直接修改原文件,没有确认缓冲,一个替换模式写错,整个文件的内容就全乱了。
它还能做很多替换之外的事,比如按行号删除:sed -i '3d' file删除第三行,sed -i '10,20d' file删除第 10 到 20 行。在一次清理脚本残留的配置时,这个用法帮我省了大量手工编辑的时间。
3.3 awk 其实很简单:理解“逐行处理”之后一切都顺了
很多人一看到awk就头大,因为它看起来像一种小型编程语言。我换个角度解释:awk的本质是“把每一行按分隔符切分成多个字段,然后按你指定的逻辑处理这些字段”。
最经典的用法是:
awk '{print $1, $3}' file.txt$1是第一列,$2是第二列,以此类推。默认按空格切分,你也可以用-F:指定冒号作为分隔符。比如取/etc/passwd里的用户名,awk -F: '{print $1}' /etc/passwd就搞定。
awk还能做统计求和这类操作。统计一堆数字的总和:
awk '{sum += $1} END {print sum}' numbers.txtEND块表示所有行处理完之后执行一次。这种写法看起来高端,其实逻辑特别直观:逐行累加,结束后输出。
我的核心建议是:不要试图一次性把所有awk语法都学会,先记住print、-F、END三个点,优先解决“我怎么把某个字段抽出来”的问题。后面熟了,再慢慢接触条件过滤和格式化输出。
3.4 组合拳:用管道把三件套串成一条处理链
真正让人感觉 Linux 好用的时刻,是管道把多个小工具串起来的时候。我给你一个真实场景:线上服务日志突然出现一批请求超时,我想快速看一眼超时请求的来源 IP 分布,以及每个 IP 出现的次数。
先抽出包含超时字样的行,再抽出 IP 列,再做去重统计,最后取前十名:
grep "timeout" /var/log/app.log | awk '{print $NF}' | sort | uniq -c | sort -rn | head -10这个管道里的每一步都很简单,但组合起来解决了一个具体问题。你不需要写复杂的脚本语言,纯靠命令组合就能完成一次粗粒度的分析。
这里有个小经验:sort | uniq -c是做统计的固定搭配,uniq -c会统计每行连续出现的次数,所以必须先sort让相同的行排在一起。而最终要按数量从大到小展示,再加一步sort -rn。第一次用的人经常忘记先排序,结果发现统计结果不对。
4. 进程与资源排查:服务器卡了先看什么,再干什么
4.1 一次真实的“服务器卡顿”排查链路
我还记得有一次运维告警说测试环境响应很慢。登录上去,第一件事不是猜,而是看整体负载。执行top,发现有一个 Java 进程 CPU 占用接近 300%,再按P键按 CPU 排序,定位到具体 PID。
接下来想知道这个进程是干什么的,用ps -ef | grep PID或者ps -fp PID查看完整启动命令。结果是个定时任务把某个数据处理脚本跑炸了,输入数据比预期大了几十倍,直接把 CPU 拖死了。
排查链路的顺序是:top看全局,ps看细节,kill或调整脚本参数后收尾。如果一上来就ps找进程,少了整体视图,很容易在错误的进程上浪费时间。
4.2 top 的界面到底在看什么,以及它不能告诉你什么
top第一行显示系统运行时间和负载均值,这三个数字(如0.50, 0.30, 0.20)分别代表过去 1 分钟、5 分钟、15 分钟的平均负载。负载不是简单的百分比,它跟 CPU 核心数有关。
如果负载值持续高于核心数,说明系统已经过载;如果只是瞬间冲高,往往是任务尖峰,不用太紧张。
top里的%CPU也常被误解,多核环境下某个进程的 CPU 可以超过 100%,我见过刚接触的人看到 200% 以为系统出 bug 了,其实那只是多核并行占用的正常表现。
要留意的是,top默认只显示一次快照,属于瞬时值。要持续观察,按c显示完整命令行,按M按内存排序,按P按 CPU 排序。这些在排查时按一下就能切换视图,非常实用。
4.3 内存问题要用 free 看,但要理解 buff/cache
free -h查看内存时,最让人困惑的是buff/cache这一列。很多人一看到这一列占用好几个 G,就以为内存不够了。
其实buff/cache是内核把读过的文件数据缓存起来了,目的是加速后续访问。当某个应用需要更多内存时,这部分缓存是可以被回收释放的,所以它不是你真正需要担心的“占用”。
判断内存是否紧张的正确指标是看available这一列,它表示在不触发交换的情况下还能给新进程分配多少内存。当available很低,同时Swap使用持续增长时,才说明内存真的吃紧了。
我习惯在排查优化类问题之前先记录一下free -h的基线,调整参数后再对比一次,有数据支撑的结论比感觉靠谱得多。
4.4 进程状态和后台任务的坑
用ps -ef看进程时,STAT列里你可能会看到Z,这代表僵尸进程。僵尸进程是已经结束但没被父进程回收的残留进程,它不占 CPU,但会占着进程表条目。
有一次我排查一个 API 服务频繁重启,最后发现每重启一次就残留几个僵尸进程,积少成多把进程数上限耗尽。解决思路不是一个个手动清理,而是找到僵尸进程的父进程,看它的处理逻辑为什么没有回收子进程。这是个反复出现的经典坑:看到Z不要只想着kill,kill对真正的僵尸进程根本无效,必须处理父进程才行。
此外,nohup和&也是新手常问的:“我关掉终端,程序会不会停?”默认情况下,终端退出会向子进程发送挂断信号,程序就会退出。所以常驻后台时用nohup command &,或者更现代的方式是用systemd管理服务。这条经验在部署脚本时非常重要——不打算挂在终端上的任务,一定要设计好脱离终端的方式。
5. 权限、用户与安全的日常边界
5.1 读懂权限位,才能解释那些奇奇怪怪的报错
Permission denied是最常见也最容易被误判的报错。我在帮人排查时,发现大多数人第一反应是“加sudo”,而不是先看权限位本身到底怎么回事。
三个权限组(属主、属组、其他用户)各有一位读、写、执行权限。文件 644 意味着属主可读写,组和其他人只可读;目录 755 意味着属主能读写执行,其他人只能读和执行。
我经常说,目录的执行权限在某种程度上比读权限更敏感。因为一个目录如果没有执行权限,你无法进入这个目录去访问里面的任何文件,即使你名义上有文件读权限。理解这个逻辑之后,你再看到 “可以列出目录内容但打不开文件” 的怪现象,心里就有数了。
5.2 chmod、chown 的正确使用姿势
chmod 755 script.sh给脚本加执行权限,chown -R app:app /data把目录属主改成应用账号。这两条命令本身很简单,坑在于递归参数-R。
我见过同事在项目目录执行chown -R root:root .,结果把一堆配置文件全部改成 root 所有,导致应用启动时没权限读写自己的配置。改回来也麻烦,因为你得先把所有文件的属主重新梳理一遍。所以逐层分配权限时要特别谨慎,先精确到文件试用,再决定要不要递归整个目录。
另外一个细节:脚本是否需要执行权限,要看你运行它的方式。用bash script.sh直接解释执行时不需要x权限;但如果是./script.sh独立执行,就必须有执行权限。这个区别经常让新手疑惑为什么有时候明明写完脚本却提示权限不够。
5.3 sudo 和 visudo:别随手给自己种下安全隐患
sudo给普通用户提权执行,避免所有操作都顶着 root。但一个常见错误是持续使用sudo -i切到 root 环境后,分不清当前身份,把普通用户的配置改到了 root 的路径下。
系统里通过/etc/sudoers文件控制谁能执行哪些提权命令。系统建议用visudo编辑这个文件而不是直接用vi打开,因为visudo带语法检查,能避免写错配置导致整个sudo机制失效。
我给新人的建议很简单:能用普通用户完成的日常操作,绝不切 root;必须提权时用sudo加具体命令;每个命令都明确知道自己在用哪个身份操作。养成这几个习惯,权限相关的低级事故能减少一大半。
5.4 umask:新建文件的默认权限从哪里来
文件默认权限不是凭空来的。umask是个掩码,决定新建文件时要去掉哪些权限位。常见值022意味着新建文件通常得到 644,新建目录得到 755。
如果你发现自己创建的文件总是意外缺少写权限或者组内其他人有权访问,多半是umask设置与预期不符。在给团队共享目录部署脚本时,我会先统一约定umask的取值,避免 A 创建的文件 B 改不了这类协作问题。
6. 让命令行真正“顺手”的组合技
6.1 管道与重定向:把每个小工具当作乐高积木
管道的哲学我今天已经强调了好几次,因为它真的是 Linux 命令组合的灵魂。管道符|把左边命令的输出接给右边命令的输入,就这么一个机制,让你可以用一堆小工具拼出任何处理链。
重定向则决定输出去哪。> file覆盖写入,>> file追加写入,2> error.log单独记录错误输出。我见过最多的问题是把正常输出和错误输出混在一起,排查时看到的日志缺一半,就是因为漏了2>&1这个常见写法。
很多脚本、定时任务里会看到command >> app.log 2>&1,它的意思是:把标准输出追加到日志文件,同时把错误输出也一并转到同一个文件。这样日志才完整,排查时才不会漏掉关键错误信息。
6.2 alias 与 .bashrc:给自己建一套顺手的快捷键
alias ll='ls -alF'可以让你敲ll得到一串常用参数的结果。适合把那些每次都要重复输入的长命令缩短记忆成本。
长期要用的alias应该写进~/.bashrc,改完之后执行source ~/.bashrc重新加载。
我自己常用的几个alias都跟查看日志有关,比如alias todaylog='tail -f /var/log/app/$(date +%F).log'。这里用date +%F动态拼出当天的日志文件,每天敲出来都是当天文件,算是一个很实用的小技巧。
6.3 history、Ctrl+R 与逆向搜索的复用价值
不知道命令全名没关系,最要紧的是知道某个命令用过,可以把它捞回来。按Ctrl+R进入逆向搜索模式,输入关键字就能匹配历史命令。直接按上方向键逐条翻历史,在大量命令记录面前效率太低。
history的输出每条都有编号,执行!123可以重新运行编号对应的命令。如果恰好要重复执行上一条命令,直接打!!。
偶尔我发现历史记录不够长,想找的命令找不到,这时候去检查环境变量HISTSIZE,它控制历史命令保留数量。默认值可能只有一两千条,对于维护机器时间较长的人来说,适当调大这个值对复盘排障很有帮助。
6.4 定时任务 crontab 的两个常见翻车现场
crontab -e编辑当前用户的定时任务,语法是分、时、日、月、周加命令。最容易翻车的点有两个。
一是环境变量。cron执行命令时的环境非常精简,不会自动加载你的~/.bashrc里设置的环境变量。写脚本时依赖某个PATH路径下的命令,结果定时执行时找不到命令,就是这个原因。我通常会在脚本开头明确设置PATH,或者用命令的完整路径。
二是输出。如果不做重定向,定时任务的输出会尝试通过系统邮件发给用户,邮箱如果没配好,输出就无声无息地丢失了。养成习惯把每次任务的运行结果写入日志文件:
0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1这样任务跑没跑成,翻日志一目了然,不用猜。
6.5 tar 打包解压的几个安全习惯
打包一个目录用tar -czvf archive.tar.gz /path/to/dir,解压到指定目录用tar -xzvf archive.tar.gz -C /target/dir。参数极多,但绝大多数时只需要记住这三件套的排列。
安全习惯方面,解压之前先执行tar -tzvf archive.tar.gz看压缩包里的内容清单。这个习惯帮我避免过好多次恶意软链接或路径穿越问题,也防止把一堆文件直接摊在错误的目录里。
另一个点:打包时建议去掉绝对路径前缀,使用相对路径。如果你用绝对路径打包,解压出来会自动落到原来的绝对路径位置,这在你只传一个压缩包给别人时会变成一场灾难。用相对路径进入目录再打包,解压到哪都由接收方自己决定。
我个人在实际操作中最深的体会是,Linux 命令的学习曲线根本不是爬坡,更像是拼图。你不需要把所有块都抓在手里才能看到全貌,而是先拼出一个小角,比如“我会用grep查日志了”“我会用find找文件了”,然后从这个角往外推,每遇到一个新问题就补一块新拼图。时间长了,你会发现真正沉淀下来的不是命令列表,而是一套处理问题的直觉——看到异常现象,知道该往哪个方向查;看日志报错,知道该用什么工具把线索抽出来。这个直觉比背一百条命令都值钱。
最后再分享一个小技巧:每次因为某个命令解决了问题之后,花三十秒对自己说一遍“我刚才用这条命令解决了什么问题”。这个动作看起来笨,但坚持几个月,你会发现自己慢慢不需要再查命令手册了。Linux 的生态里永远有学不完的细节,但把核心命令挂到自己的问题场景上,日常工作的八成需求就已经完全够用了。