接触Linux这些年,最常被问的问题不是"哪个命令最难",而是"到底该学哪些命令"。网上不少文章喜欢把命令按字母表列一遍,看着很全,实际用不上几行。我根据自己日常在服务器和本地环境的实操,从目录定位、文件操作、文本处理、进程管理、磁盘维护、网络请求这几条主线里,筛出了30个出现频率最高的Linux命令。它们不是背就完事的知识点,而是一套可以直接上手的终端工作流。
无论你是刚装好Linux发行版的新手,还是平时只在服务器上执行固定几个命令、遇到点变化就抓瞎的"半熟手",这篇内容都值得你花半小时从头过一遍。图形界面点得再溜,一进终端就发怵的人我见过太多了。终端并没有那么可怕,它只是换了一种交互方式,核心逻辑反而更直白:把人要做的操作,用命令告诉系统去执行。这30个命令,就是我和命令行打交道多年后最想推荐的"最小必要集",覆盖日常文件管理、日志排查、资源监控、打包发布这些高频场景。
1. 终端玩法变了,但命令行思维没变:先搞懂三件事再做命令党
1.1 为什么终端在今天依然是"必学"技能
有人会觉得,现在Linux发行版的桌面环境做得挺好了,文件管理器、任务管理器、系统监视器一应俱全,为什么还要记命令?我一般用一个例子回答:假如你手里有100个文件,要把其中所有名为photo_*.jpg的文件统一改成img_*.jpg,用图形界面一个一个重命名,至少得折腾半小时。而命令行动手只需要一行rename或者一个循环。
更深一层的原因是,服务器环境几乎没有图形界面可言。你买了云主机、租了远程节点,摆在你面前的通常只有一个SSH终端窗口。不会命令行,就等于不会操作这台机器。再往大了说,脚本自动化、定时任务、日志分析、服务排查,这些工作本质上都是命令的排列组合。图形界面适合"点一点看看状态",命令行适合"精确地做成一件事情",两者不是替代关系,而是互补关系。
1.2 命令的"三段式"结构与man命令
要玩转终端,先理解命令的通用结构:命令本体 + 选项 + 操作对象。比如ls -l /var/log这一行,ls是命令本身,-l是选项(让输出变成长格式),/var/log是操作对象。绝大多数命令都逃不开这个骨架,个别命令的选项可以组合,比如ls -lah,等同于ls -l -a -h。
说到这儿,必须把30个命令里的第一个请出来:man。它的全称是manual,用法极其简单——man ls,然后屏幕上会展示ls的完整手册,按q退出。有些新手不知道在man页面里怎么翻页,其实方向键上下滚动、空格翻下一页、/搜索关键词、q退出,就这四个操作。
我强烈建议你养成一个习惯:接到一个不熟悉的命令,第一反应不是去搜索引擎里翻博客,而是先跑man 命令名。虽然手册英文居多,但内容权威、参数完整,比网上很多二手教程靠谱得多。man本身不算花哨,却是所有命令的"老师",所以它必须排在30个命令的第一个。
另外,在进入下一节之前,请在心里记住两个符号:>和|。>叫重定向,作用是把命令的输出写进文件;|叫管道,作用是把前一个命令的输出,当作后一个命令的输入。它们是后面所有"组合玩法"的地基。
2. 文件和目录操作:从"增删改查"闭环开始
这一组包括9个命令:pwd、cd、ls、mkdir、touch、cp、mv、rm、find。它们解决的是"我在哪、这里有什么、怎么创建、怎么移动、怎么删除、怎么查找"这些最基础的问题。相信我,把这9个练成肌肉记忆,你在终端里就已经不是纯新人了。
2.1 定位与查看:pwd、cd、ls
pwd(print working directory)用来打印当前所在目录的绝对路径。它的使用场景很明确:当你从一个目录不断深入之后,往往会迷失方向,尤其是有软链接、符号路径存在的情况下,pwd能帮你确认当前到底站在哪个位置。这里有个小细节:默认的pwd显示逻辑路径,如果当前目录是通过符号链接进入的,它会显示链接路径;但pwd -P可以显示物理真实路径。排查路径问题时,这两个结果不一样的情况经常让人掉坑。
cd(change directory)是切换目录的命令,用法不用多说。我想强调三个快捷写法:cd ~回到当前用户的家目录;cd -回到上一次所在的目录;cd ..返回上一级目录。其中cd -是我在工作里用得极其频繁的一个操作,在两个目录之间来回切换时,它省掉了重新打一长串路径的麻烦。需要留意的是,cd命令的选项很少,工作日常用的就是路径跳转。
ls(list)是列出目录内容。我最常用的组合是ls -lah:-l列出权限、属主、大小、修改时间等详细信息,-a显示隐藏文件(以.开头的文件),-h把文件大小显示成人类易读的KB/MB/GB。很多人到了这一步就结束了,但我想提醒一个实用细节:如果你想要按时间排序,在完整信息列表下加-t,比如ls -lah --time-style=long-iso,这在找"刚刚被改过哪个文件"时特别好用。
2.2 创建、复制、移动、删除:mkdir、touch、cp、mv、rm
mkdir创建目录,最重要的选项是-p:一次性创建多级目录。举个实际例子,mkdir -p data/2025/01,执行一次就会连父目录带子目录全部建好,不会因为中间目录不存在而报错。如果在脚本里建目录,我几乎总会在mkdir后面加-p,这是防御性写法,目录存在时它不会报错,不存在时自动帮你建。
touch创建空文件的用法大家都会,但我更常用它的另一个用途:更新时间戳。当一个文件或目录需要刷新访问时间、修改时间时,touch file就能做到。很多构建工具、日志轮转脚本里都会靠touch来触发某些文件变化,知道这个底层动作,遇到"什么都没变,但这几个时间变了"的现象时,就不会觉得玄乎了。
cp复制文件或目录。复制单个文件直接cp 源文件 目标文件,复制整个目录必须加-r,否则会报错。我推荐你直接记cp -a这个组合,-a等于-r再加保留权限、属主、时间戳等全部属性,做整目录备份时最合适。第一次用cp的人经常会问"为什么复制目录老是报错",其实就是差一个-r的事情。
mv移动文件或目录,但它有个巧妙用途:在同一目录内mv oldname newname,就是重命名。所以mv命令是"移动"和"重命名"一体的。在跨文件系统移动时它可能先复制再删除,速度会变慢,但行为上你不用关心,交给系统处理就行。
rm删除,这是所有命令里最需要敬畏感的一个。rm -rf这个组合,-r递归删除目录内容,-f强制不询问,一旦路径写错,就可能把整个项目甚至系统删掉。我的实操经验是:第一,生产环境的删除命令里,路径务必写绝对路径,写完后看一眼再回车;第二,重要数据提前备份,或者用带回收站机制的替代方案;第三,尽量别在root状态下跑rm。这个命令本身很简单,风险全在使用者的纪律。
2.3 用find找文件,别靠肉眼翻
当你面对一个几百GB的项目目录,想找某个文件时,ls加通配符已经不管用了,该find上场。
find的常用组合大概是这样的:find . -name "*.log"在当前目录递归查找所有log文件;find /var/log -type f -mtime +7查找7天前被修改过的文件;find . -size +100M查找超过100MB的大文件;find . -type d -name "node_modules"查找所有名为node_modules的目录。注意,find查找的是文件系统的实时状态,不是字符串匹配,所以它比很多IDE内置的"全局搜索"更底层、更灵活,尤其是在服务器上定位大文件、清理缓存时,find是不可替代的。
还有一个小组合我也常用:find . -name "*.py" | xargs grep "TODO"。xargs会把前一个命令输出的每一行作为参数传给后面的命令,这样就能在"所有Python文件里搜索TODO标记"。xargs虽然没进我这30个名单,但你迟早会想学它。
3. 文本查看与管道玩法:终端效率的真正分水岭
这一组是11个命令:cat、less、head、tail、grep、wc、sort、uniq、cut、tr、tee。为什么单独开一章?因为Linux文件的世界里,文本占据了绝对主流:日志、配置、脚本、数据文件,全都可以用文本命令处理。学会了这一组,你才真正开始感受到命令行的威力。
3.1 从cat到less,从head到tail
cat(concatenate)的原始作用是拼接文件,比如cat a.txt b.txt > c.txt。但日常更常用的是快速查看小文件的内容。一旦文件行数很多(比如几百行以上),cat会把所有输出直接砸到终端上,屏幕滚动根本来不及看。这时候要用less。
less是一个分页查看器,它允许你上下滚动、搜索、翻页,而且加载大文件非常高效。文件再大也不必担心一次性读入内存。进入less之后,/可以搜索,n跳到下一个匹配结果,q退出。我习惯的用法是less -N 文件,开启行号显示,方便定位到具体行或者把行号告诉同事。
head和tail分别查看文件开头和结尾。推荐用法:head -n 20 file查看前20行,tail -n 50 file查看最后50行。但tail有一个杀手级的选项:-f。执行tail -f /var/log/syslog之后,终端会保持跟踪状态,文件有新内容写入时自动滚动显示,这就是大家常说的"实时看日志"。排查线上问题时,一边用tail -f盯着日志,一边重现故障场景,是最经典的调试姿势。停止跟踪按Ctrl+C。
打个比方,cat是翻开一本小册子从头看,less是你能随意翻页甚至搜索的阅读器,tail -f则像一场实况直播,后续内容自己不停滚进来。
3.2 管道五件套:grep、wc、sort、uniq、cut
grep是文本检索的明星,按行匹配模式。常用的选项有这么几个:-i忽略大小写,-n显示匹配行行号,-r递归搜索目录,-v反向匹配(排除包含关键字的行),-c统计匹配行数,--include限定文件类型。比如排查一段日志中哪些请求返回了错误码:grep "ERROR" app.log,配合-n直接定位到报错行。如果没有重点概念,看日志基本是瞎看;有grep之后,你可以在几十万行日志里瞬间捞出关键行。
wc(word count)用于计数。最常用的参数是-l,统计行数。例如grep "ERROR" app.log | wc -l,输出这一天日志里ERROR出现的总行数。这也是脚本判断有没有异常的手段之一。
sort排序,uniq去重,这两个组合起来才真正强大。sort默认按字典序排列,数字排序要加-n,反向排序加-r;uniq单独使用只能去掉相邻重复的行,所以必须先排序再uniq,才能去全局重复。最有用的组合是sort | uniq -c:-c会统计每行出现的次数,并给每行加上计数前缀。这个组合在统计日志里"哪些IP访问最多"、"哪个错误码出现最频繁"时,无可替代。
cut用来按列裁剪文本。最典型的是cut -d: -f1 /etc/passwd,以冒号为分隔符,取出第一个字段,得到的是系统所有用户名。换成日志场景,比如某行日志是"IP 时间 状态",用cut -d' ' -f1可以只取第一列IP。配合sort和uniq,就形成了一条简单但有效的统计流水线。
这里给个真实例子:统计access日志里访问量前五的IP。
tail -n 10000 access.log | cut -d' ' -f1 | sort | uniq -c | sort -rn | head -n 5从结果来看,左侧就是访问次数,右侧是IP地址,前几名是谁一眼可见。这个一条龙组合里,每条命令职责单一,却通过管道完美协作,软件工程的"高内聚低耦合"在终端里体现得淋漓尽致。
3.3 tr和tee:字符转换与输出记录
tr(translate)做字符层面的替换、删除。典型用法:cat file.txt | tr 'a-z' 'A-Z'把小写全部转大写;tr -d '\r' < file.txt删除Windows换行符里的回车符,这在处理不同平台间传递的脚本文件时经常救命。注意tr默认读标准输入,所以它通常是管道的一部分,而不是直接接文件名参数。
tee的作用是"分流":它从标准输入读取内容,同时写入标准输出和指定文件。最常见的场景是,在跑一个长时间任务时,既想在屏幕上实时看到输出,又想把它完整保存到日志文件里。写法是:command | tee run.log。如果你还想追加而不是覆盖,加-a选项。有个细节我提醒一下,tee不会影响管道的下一站,所以command | tee run.log | grep "success"完全可以继续往下过滤输出。
4. 权限与进程:别让机器变成"谁都能碰"的裸奔现场
这一组是5个命令:chmod、sudo、ps、top、kill。文件和文本处理解决的是"怎么操作数据",这一组解决的是"谁能操作、谁正在运行、怎么停下不该跑的进程"。系统安全与稳定性,全靠这几个命令撑起来。
4.1 chmod与sudo:权限位的边界感
chmod修改文件或目录的读、写、执行权限。Linux里权限分成三组:属主(u)、属组(g)、其他用户(o),每组三种:读(r)、写(w)、执行(x)。数字表示法非常直观:读是4,写是2,执行是1,相加得到该组权限值。常见的chmod 755代表属主有全部权限(7=4+2+1),属组和其他用户有读和执行权限(5=4+1)。脚本文件要能执行至少要+x,所以chmod +x script.sh也是高频操作。
一个真实教训:有次我把一个包含数据库口令的配置文件权限设成了644,这意味着同机器上的所有用户都能读它。虽然当时只是测试环境,但这类习惯一旦带到生产环境,就是严重的安全隐患。现在我的默认做法是:敏感文件权限设成600(仅属主可读写),目录设成700(仅属主可进入),除非确有共享需求,否则不轻易放开权限。
下表是几个常用权限值,建议贴在手边:
| 权限值 | 属主 | 属组 | 其他用户 | 常见用途 |
|---|---|---|---|---|
| 600 | 读写 | 无 | 无 | 密钥、口令文件 |
| 644 | 读写 | 读 | 读 | 普通配置文件 |
| 700 | 读写执行 | 无 | 无 | 私有目录 |
| 755 | 读写执行 | 读执行 | 读执行 | 可执行文件、脚本、公开目录 |
sudo让你以另一个用户身份执行命令,默认是root。它解决的问题是"需要管理员权限时不至于裸奔用root"。但我经常提醒身边的新手:sudo不是免死金牌,sudo rm -rf /该炸还是会炸,甚至因为权限更大,破坏性也更强。我的使用原则有两条:第一,能用普通用户完成的日常操作,绝不加sudo;第二,必须加sudo的命令,先想清楚命令立刻会干什么,再回车执行。对sudo的谨慎,本质上是对系统边界和自身操作风险的敬畏。
4.2 ps、top、kill:发现进程并优雅收尾
ps用来查看当前进程的快照。最经典的组合是ps aux,不加短横线,逐行列出所有进程。输出里比较关键的字段有:USER进程属于哪个用户,PID进程号,%CPU和%MEM占用率,STAT当前状态,COMMAND启动这个进程的命令。服务器上某个进程CPU飙到100%、内存暴涨,第一时间就是ps aux找到可疑进程的PID。
top是动态版的进程监控,类似图形任务管理器,定时刷新。在top界面里,按q退出,按M按内存排序,按P按CPU排序,按k可以输入PID并发送信号终止进程。如果默认的top界面信息太多,输出有点杂乱,可以重点看顶部几行的负载平均值和内存总量,下面的进程列表看那个CPU占用率排第一的家伙是谁。
kill用于向进程发送信号。这里有个常见误区:以为kill就是"杀死进程"。其实默认的kill -15发送的是SIGTERM,请求进程体面地退出、清理临时文件和释放资源;只有进程软硬不吃时,才用kill -9发送SIGKILL强制杀掉。我排查线上问题时的顺序永远是先kill -15 PID,等几秒钟,如果进程还在,再kill -9 PID。动不动就-9,虽然能达到目的,但可能导致数据没来得及落盘,留下后遗症。
举个完整例子:如果你的服务脚本挂死了,可以这样定位和清理:
ps aux | grep my_service # 找到PID之后执行 kill -15 12345 # 过几秒没退出的话,再执行 kill -9 123455. 磁盘空间与打包:运维最常用,却最容易掉坑的硬功夫
这一组是3个命令:df、du、tar。命令不多,但它们牵扯一个高频事故:"磁盘满了"。我处理过太多次这类告警,每次排查思路几乎固定:先df看分区,再du揪出大目录,最后按需清理或打包归档。
5.1 df和du:先看分区,再看目录
df(disk free)查看文件系统的整体使用情况。最常用的是df -h,-h把容量显示成人类易读的GB,加了这条看输出全是"G"和"M",不像默认的KB数多得吓人。执行后你会看到类似这样的表格:文件系统、总容量、已用、可用、使用率、挂载点。注意有几个挂载点是虚拟文件系统,不是真实磁盘,重点是看挂载在/下的那一行。
du(disk usage)统计目录占用的实际空间。注意用户经常陷入一个误区:直接用du统计整个根目录,扫描速度非常慢。正确做法是逐层深入,先看当前目录下每个子目录的大小,再进入嫌疑最大的那个继续看:du -sh *,前提是先在目标目录下执行。其中-s是汇总当前层目录总大小,-h是易读格式。
磁盘告警的标准排查流程是:先跑df -h确认哪个分区满了,再进入该分区的挂载目录,逐层du -sh *。三步之内就能锁定最大的"磁盘杀手",有时候是个日志目录,有时候是个临时缓存目录。确认后删掉过期文件,或者用tar打包归档到其他机器,问题就解决了。
5.2 tar:打包压缩与解压,一套参数带走
tar是归档工具,本身不做压缩,真正的压缩由gzip完成,但tar整合了两者。最常用的创建命令是tar -czvf archive.tar.gz /path/to/dir,解压命令是tar -xzvf archive.tar.gz,注意解压时如果希望释放到指定目录,加-C 目标目录。
这四个字母背后是四个参数:c创建归档,x解包,z表示用gzip压缩/解压,v显示处理过程中的文件列表,f后面紧跟归档文件名。很多人会疑惑"为什么要记顺序",其实严格说tar的参数顺序有一定要求,f后面必须直接跟文件名,所以它被大家约定放在最后。一个比较隐藏的点是:如果你的包是.tar.gz但扩展名写成了.tgz,tar同样按gzip处理,这套参数不变;如果是.tar.bz2,把z换成j即可。
解压之前有个安全习惯:先跑tar -tzvf archive.tar.gz查看包内文件列表,确认内容符合预期再真正解包。尤其从网上下载的压缩包,先看看里面有没有奇怪的路径符号(如../../),避免解压时覆盖系统目录,这是我多次踩坑后留下的条件反射。
打包时还有个小技巧:想排除某些大文件目录,用--exclude参数,比如tar -czvf archive.tar.gz --exclude='data/cache' /var/www。这样备份时既完整,又不必把几G的缓存一起打包。
6. curl从查接口到下文件,以及几个我强烈建议补学的终端习惯
最后一组只有一个正式入选命令:curl。别嫌少,curl一个顶好几条,它能完成HTTP请求、下载、上传、接口调试,几乎就是命令行里的"浏览器"。剩下的篇幅,我想分享3个虽不在30个名单里、但效率收益极高的终端习惯,顺手学会它们,你的终端体验会上一个台阶。
6.1 curl:终端里的"远程访问"
curl最基础的用法是直接跟一个URL,把内容下载到标准输出。日常高频场景有三个:第一,curl -I https://example.com,-I只获取响应头,不拉取整个内容,用来快速确认目标服务的状态码、Server类型、响应时间;第二,curl -O https://example.com/file.tar.gz,-O把远程文件名保存到本地,等价于命令行版"下载文件";第三,调试API时,curl -X POST -H "Content-Type: application/json" -d '{"name":"test"}' https://example.com/api,向接口发送POST请求,把服务器返回的JSON直接打到终端上供你检查。
接口出问题时,我经常在服务器上用curl做最小化验证。比如怀疑某个服务挂了,先curl -I 本地地址,看是连接拒绝还是超时;如果返回200,说明服务本身活着,问题大概率出在前面的代理或防火墙。这一步能快速缩小排查范围。还有一个细节:自签名证书的HTTPS接口,curl默认会拒绝,调试时加-k可以跳过证书校验,但就别指望它在生产场景里用,那只是为了本地测试方便。
6.2 30个之外的三个好习惯:Tab补全、alias、history
Tab补全不是一条命令,却比很多命令都重要。输入命令路径时按一次Tab自动补全,连按两次显示所有候选。我曾经见过有人还在手打systemctl然后试图背出服务名,其实只需输入前几个字母然后按Tab,系统会帮你列出所有可能项。这个习惯把"记命令"变成"猜命令",心理压力骤减。
**alias(别名)**让常用长命令变短。在~/.bashrc里写上alias ll='ls -lAh --color=auto',重新加载后就能用两个字母完成原本一长串的操作。我个人积累了不少易用的别名:alias ..='cd ..'、alias gs='git status'、alias home='cd ~'。不过要注意,别名不能覆盖到非交互式shell,想让脚本也用,得单独写在系统的profile里。
history查看命令历史,是我用来复盘操作痕迹的重要工具。直接敲history会列出所有执行过的命令,配合grep搜索曾经用过的方法:history | grep "tar"就能找出你以前是怎么打tar包的了。如果你想执行历史里第123条命令,!123直接重新执行,省去重新打一遍的麻烦。
我自己的体会是,把这30个命令串成肌肉记忆之后,终端带给你的反馈是即时的、精确的,也是图形界面很难替代的。别急着背,先打开一个终端,把第2章和第3章的命令逐个敲一遍,遇到不会的选项就man一下,再回来读这篇文章的其余部分,信息的吸收效率会高很多。