ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux常用命令实战:从命令背诵到组合排障的思维升级

Linux常用命令实战:从命令背诵到组合排障的思维升级

前端时间有个朋友问我,能不能给他一份“常用的Linux命令”清单,他说自己收藏了好几份所谓的命令大全,但遇到问题的时候还是不知道该用哪个。我其实特别理解这种感觉——Linux命令不是背出来的,是用出来的。真正常用的命令数量并不多,关键是要建立一套怎么把命令组合起来解决问题的思路。

这篇文章我不会给你罗列几百条命令,也不会搞什么“必背100条”的噱头。我会把日常参与服务器维护、日志排查、文件管理和自动化脚本时最常用、最扛得住活的那几条命令拆开讲透,告诉你每条命令解决什么问题、为什么这么用,以及哪些坑是我自己踩过之后才明白的。无论你是刚接触Linux的初学者,还是已经有几个月经验、想系统梳理一遍的从业者,都可以拿着这篇文章当一份操作地图。

1. 为什么照着命令大全背,遇到实际问题还是不会用

1.1 命令的真正价值在于“组合”,而不是单条语法

很多人学Linux命令,习惯打开一张所谓的“命令大全”,把ls -l、cp -r、grep -i一条条读过去,然后背下来。问题在于,真实工作里极少有场景是“输入一条命令就完事”的。你排查一次服务启动失败,可能需要先用systemctl看服务状态,再用journalctl看日志,接着用grep过滤日志关键词,用tail查看新增内容,最后用sed或者awk提取关键字段。整个过程是五六个命令连续协作的过程,而不是单个命令的孤立使用。

我自己带过几个新人,发现他们最明显的卡点就是:单独问某条命令的某个参数,能答得头头是道;一放到真实故障场景里,思路就断了。原因很简单,他们脑子里装的是“命令词典”,而不是“任务地图”。所谓任务地图,就是你看到一个需求,能先判断它属于“文件操作”“文本处理”“进程管理”还是“网络排查”,然后自然选出对应的那组命令来配合。这也是我把文章主体按“任务”而不是按“命令字母表”来组织的原因。

1.2 搭建自己的命令学习闭环:动手、查询、复盘

我建议的学习路径不是“先背再练”,而是“先练再查”。你拿到一台云服务器或者本地虚拟机,给自己定一个真实的小任务,比如“找出日志里今天报错次数最多的接口,并按次数排序”。这个任务本身就会逼着你去用grep、awk、sort、uniq,而且用完之后你很难忘记,因为你是带着问题学的。

遇到记不清的参数,就用man命令或者--help现场查,不要硬背。Linux命令的参数非常多,没人能全部记住,只要记住高频的那几个就够了。比如ls你真正高频用到的无非是-l、-a、-lh,剩下的完全没有必要背。查完参数之后,建议自己在终端里多敲两遍,甚至故意换几种参数看看输出差异,这个“试错过程”会大大加深记忆。最后,我还会习惯把常用的组合命令存进一个笔记文件里,方便下次直接复制改改就用。

2. 文件和目录处理:先让导航、创建、复制和定位变得顺手

2.1 在文件系统中导航:让路径理解成为本能

日常使用Linux,最先打交道的一定是文件系统。pwd用来查看当前目录,cd用来切换目录,ls用来列出目录内容。这三个命令看起来太简单了,但很多人在路径理解上其实是有欠缺的。

比如cd切换目录时,相对路径和绝对路径的区分就非常重要。绝对路径是从根目录/开始写的完整路径,例如/etc/nginx/nginx.conf,不管你在哪个目录下,它指向的都是同一个位置。相对路径则是相对于当前目录的路径,例如你人在/etc/nginx下,直接执行cd conf.d就能进入它的子目录。另外一个容易忽略的是cd -,它会把目录切回上一次所在的位置。这个命令在排查问题时特别有用,你从项目目录跳到日志目录,看完日志想回来,直接cd -就够了,不用再打一长串路径。

说回ls,它最常用的三个参数是-l(输出详细列表)、-a(包括隐藏文件)和-h(把文件大小显示成人类易读的格式)。这三者经常组合成ls -lah使用,我在任何一台服务器上几乎都会先用这个命令看一眼目录内容,因为它的输出信息量最大:文件权限、属主、属组、大小、修改时间一目了然。目录项太多的时候,还可以接管道用less分页查看,这个组合我在后面讲文本处理时会展开。

2.2 创建、复制、移动和删除文件的基础操作

先记住几个最高频的命令:touch创建空文件,mkdir创建目录,cp复制,mv移动或重命名,rm删除。听起来简单,但实际操作里有几个非常容易出问题的细节。

mkdir最实用的参数是-p,它会把路径中缺失的所有父目录一次性创建出来。比如你要一次性创建/data/logs/nginx这三级目录,直接mkdir -p /data/logs/nginx即可,不用层层创建。而且-p还有一个隐藏的好处:如果目录已经存在,命令也不会报错,这个特性在脚本里非常好用。

cp有几个参数需要记住。-r是递归复制目录,-a相当于-r加上保留权限、属主、时间戳等属性,我特别建议在复制目录时优先考虑cp -a,因为单纯用-r复制出来的文件,时间戳会变成当前时间,某些依赖时间戳的构建流程就容易出问题。

mv在同一个文件系统内移动文件时,只是修改了文件名记录,速度很快,也不怎么占磁盘IO;但跨文件系统移动,比如从/tmp移到某个挂载盘,它会先复制再删除,涉及实际数据传输,速度会明显变慢。如果文件很大,你可能要考虑改用rsync这类支持断点续传的工具。

rm是Linux新手最容易紧张的命令,因为删错了不好恢复。我会在实操中始终坚持一个习惯:删除前先用ls确认目标路径,尤其是处理通配符的时候。比如你想删/tmp下所有临时文件,写rm -rf /tmp/*,如果路径多打了一个空格写成rm -rf /tmp /*,后果会非常严重。这种错误不是罕见,是真实发生过无数次。我自己的做法是在脚本里禁用rm -rf,改用把文件移动到/tmp/trash目录,统一清理,因为安全永远比省那几秒钟重要。

2.3 定位文件和命令:不需要记住所有东西在哪儿

真正常用的定位命令有三个:which用来查可执行命令的路径,find用来按条件搜索文件,locate用数据库做快速定位。

which是最简单的一个,比如你执行which python3,它会返回python3命令所在的具体路径。这在排查“为什么命令行里执行的和脚本里执行的不是同一个版本”时非常有用,因为机器上可能装了多个Python版本,而PATH环境变量决定了到底用哪一个。

find的能力很强,但高频用法其实很集中。最常见的是按名字找文件:find /etc -name "*.conf"就会列出/etc下所有.conf结尾的文件。另外一个实用场景是按时间找文件:find /var/log -mtime -7表示查找过去7天内修改过的文件,这在你刚部署完一套服务、想确认生成了哪些日志时特别顺手。find还可以执行操作,比如find /tmp -name "*.tmp" -delete直接删除符合条件的目标,不过这条命令我建议谨慎使用,最好先用不带-delete的形式看一遍结果。

locate的优势是快,它依靠预建数据库搜索,缺点是数据库可能不是最新的。新安装的文件没进库就会搜不到,用updatedb更新后才行。对你的日常工作而言,which和find基本够用,locate适合偶尔快速搜索系统范围文件。

3. 从输出里筛出真相:日志与文本处理命令

3.1 用grep在日志和配置里精准定位

服务器出了问题,最直接的线索就是日志。日志文件动辄几百行甚至几千行,靠人眼翻是不现实的,这时grep就是最核心的过滤工具。

我第一个要养成的习惯是:grep不光是“找关键词”,它还能“按条件过滤”。真实场景里最常用的组合是-E支持扩展正则、-i忽略大小写、-v反向匹配、-n显示行号。比如你在 Nginx 错误日志里想找所有与数据库连接相关的报错,可以用grep -i "database" error.log;如果你想排除掉健康检查的请求,可以用grep -v "health"。

还有一个我强烈推荐的高频用法,grep递归搜索目录。grep -r "timeout" /etc/nginx/会搜索整个配置目录,让你不用挨个文件打开找配置项。这里的-r跟cp的-r一样,都表示递归处理子目录。我以前排查一个网关超时配置,就是靠grep -rn "proxy_read_timeout" /etc/nginx/一秒定位到了被拆分到多个配置文件里的真实生效项。

使用grep的体验优化还要提一个场景:管道。当别的命令输出很多内容时,你可以把它接给grep做二次过滤。比如ps aux | grep nginx是所有运维人员都会第一时间做的事情,先把进程列表列出来,再过滤出和Nginx相关的。这种管道组合是Linux最经典的操作模式,第7节我会专门展开。

3.2 用head、tail、sort、uniq和wc做快速统计

日志排查里,另一组高频命令是head、tail、sort、uniq和wc。head -n 20 file查看文件前20行,tail -n 20 file查看末尾20行,这两个在“我只想看最新的报错”时非常实用。

tail -f是我最常驻终端的一个命令。-f表示持续跟踪文件新增内容,日志有新写入时它会自动刷新出来,相当于实时监控。我在调试接口的时候,经常开一个窗口执行tail -f /var/log/app.log,另一个窗口触发请求,这边立刻就能看到打印信息,非常直观。有些人用tail -f -n 50,既能看到已有日志的最后50行,又能持续跟随新内容,这个组合我也是推荐的。

sort和uniq常常一起出现。sort按字典序或数字序排列,uniq合并相邻的重复行。注意uniq只能去掉相邻的重复项,所以通常先sort再uniq才能正确去重。比如你想统计访问日志里有哪些不同的IP,可以awk '{print $1}' access.log | sort | uniq,这里第一条命令先提取出每行的第一个字段(IP),排序之后uniq去掉重复项,得到的就是唯一的IP列表。

再加上-c参数,uniq -c会在每行前面显示重复次数,再配合sort -rn按数字倒序排列,就能找出“出现次数最多的IP”或“报错最多的接口”。这个三步组合我几乎天天用:grep"ERROR" app.log | awk '{print $NF}' | sort | uniq -c | sort -rn,先过滤错误行,再提取最后一个字段,然后统计排序,得到的就是错误分布TopN。wc用来计数,wc -l表示统计总行数,适合快速确认日志增长量。

3.3 sed与awk:两个足够日常使用的片断

很多人看到sed和awk就头大,觉得它们复杂得像一门编程语言。其实日常高频需求就是两件事:sed做文本替换,awk做字段提取。

sed的高频格式是sed 's/旧内容/新内容/g',表示把每行里所有“旧内容”替换成“新内容”。例如你想把配置文件里的IP从192.168.1.10改成192.168.1.20,可以用sed 's/192.168.1.10/192.168.1.20/g' old.conf > new.conf,注意我会把结果重定向到新文件,而不是直接改原文件。直接改动原文件可以用-i参数,但这属于危险操作,建议先不加-i跑一遍看输出,确认无误后再执行。

awk的日常用法是“按列提取”。日志和表格类文本通常用空格或制表符分隔,awk '{print $1}'就能提取每行的第一个字段,$0表示整行,$NF表示最后一个字段。我前面举的统计IP和错误字段的例子,本质都是利用awk做字段提取。awk还支持自定义分隔符,例如awk -F "," '{print $2}' file.csv从CSV里提取第二列。只掌握这两条,你的文本处理能力就已经覆盖了绝大多数日常工作。

4. 权限与账号:真正理解Linux安全体系

4.1 看懂ls -l输出的十个字符,后面的操作才不会慌

Linux权限不是只有root和非root这种粗粒度概念,而是文件权限、属主、属组、其他用户三个维度构成的。执行ls -l时,第一列是一长串字符,比如-rw-r--r--,这一串其实包含了完整信息。

第一个字符表示文件类型,-是普通文件,d是目录,l是符号链接。后面九个字符分成三组,每组三个,顺序是 r(读)、w(写)、x(执行)。第一组属于文件属主,第二组属于属组用户,第三组属于其他人。例如-rw-r--r--,意思就是属主有读写权限,属组和其他人只有读权限。

目录权限和文件权限要分开理解。目录的r表示能列出目录内容,w表示能在目录里创建或删除文件,x表示能进入这个目录。最让人困惑的是,一个文件本身权限明明是rw-r--r--,但你在它的父目录没有执行权限,照样进不去目录、读取不了文件。这个“目录权限优先”的概念我建议牢牢记住,排查权限问题时,第一步就该检查从根路径到文件之间所有目录的权限。

4.2 chmod、chown最基本的正确写法

调整权限用chmod,修改属主和属组用chown。数字法是我个人最喜欢的写法,它把 r、w、x 分别记为4、2、1,想赋予哪个权限就把对应数字加起来。例如rwx是7,rw-是6,r--是4。chmod 755 file表示属主有完整权限7,属组和其他用户有读和执行权限5。

实际项目中,最常见的需求是:给脚本加执行权限,用chmod +x script.sh(这里细说下,执行权限的前提是文件本身可读);把某个目录及里面所有文件的属主改成某个用户,用chown -R 用户:组 /data/project。-R是递归处理子目录,和cp、grep中的-r含义一致。

这里有个容易混淆的点,也是我踩过的坑:chmod的数字法,它设置的是完整的权限位,而不是增量。比如原权限是755,你执行chmod 644 file,就是把属主的执行权限也去掉了。很多人以为chmod 644只是在原有基础上加上读权限,这是完全错误的理解。所以每一次用数字法修改权限,一定要把最终需要的完整权限想清楚再写。

4.3 日常账号管理与不要无脑用root

服务器一般不会只有一个人使用,涉及账号管理的命令包括whoami查看当前登录用户、id查看用户ID和所属组、useradd创建用户、passwd修改密码、usermod -aG把用户添加进某个组。

从安全角度,我最强烈的建议是:日常操作不要用root账号登录,需要提升权限时用sudo执行单条命令就好。长期使用root的最大问题是缺少审计追踪,一旦出现误操作或者机器被入侵,你很难知道是哪条命令、哪个用户干的。用sudo配合日志,至少能看到操作痕迹。

另外要给执行常用命令的用户添加相应权限时,比如希望某个用户能重启Nginx服务,正确做法是用visudo编辑sudo规则,只放行少数几条命令。我在很多项目里的通行做法是:普通账号只在必要时sudo,而且优先让成员加入一个专门的运维组,通过组权限来管理文件访问。这样既避免了“一个人全部权限”的问题,又让多人的协作干净了很多。

5. 进程与资源:一台服务器到底在忙什么

5.1 用ps和top/htop盯住进程

服务器卡顿或者资源飙升,第一个要回答的问题是“什么进程在占用资源”。ps aux是基础工具,它会把当前所有进程的用户、PID、CPU、内存、状态和启动命令列出来。输出很长,所以通常配合管道过滤,比如ps aux | grep java找出Java相关进程。

top是动态视图,它会持续刷新当前资源占用排序,默认按CPU使用率排序。打开top后,按1可以展开每个CPU核心的使用情况,按M可以改成按内存排序,按q退出。htop是top的增强版,界面更友好,可以直接用方向键选中进程然后按F9发送信号,如果你所在的服务器允许安装额外软件,我建议直接装一个htop。

这里我要提一个关键区分:top显示的CPU使用率是瞬时值还是累计值?它的默认视图是动态刷新,你看到的是此刻的采样值,所以某个进程瞬间飙高很正常,应该观察几秒钟再判断,不要一看到数字高就直接下结论说“服务出问题了”。我也见过很多刚入行的朋友,因为top里某个进程CPU瞬间50%就紧张到不行,其实只是启动阶段在加载数据,几秒后就稳下来了。

5.2 优雅地终止一个进程:从kill到pkill

很多人对kill的印象是“强制杀死进程”,其实kill是向进程发送信号,最常用的是kill <PID>对应默认信号SIGTERM,它是在请求进程自行退出,让程序有机会保存状态、清理资源。只有程序确实卡死、无法响应正常退出信号时,才应该考虑kill -9 <PID>(发送SIGKILL,强制终止),因为这种信号直接把这个进程杀掉,连清理的机会都不给。

我的建议顺序是:先用kill <PID>,等待几秒看进程是否退出,如果还不行,再考虑用kill -9。某些服务进程卡住时,直接kill -9可能会留下异常的资源文件,甚至导致重启失败,这个情况在数据库类进程上尤其明显。

按进程名批量操作时,可以用pkill nginx按名称匹配发送信号。还有一个场景,就是你在终端运行了一个前台程序,想中断它,直接按Ctrl + C即可,它相当于发送SIGINT信号。后台任务的挂起、恢复则用jobs、bg、fg,不过这些在纯前端交互时用得更少,在脚本和远程操作中反而更重要。

5.3 磁盘、内存与负载的基本判断逻辑

系统资源问题分几个层面,涉及的命令各不相同。

内存用free -h查看,人类可读的格式输出总内存、已用、空闲和缓存。要注意的一点是Linux会把空闲内存用作缓存(buff/cache),这部分缓存是可以回收的,所以“可用内存”往往比你直观算出来的空闲值要大。判断内存是否充足,更应该看 used + buff/cache 之后还有多少,而不是只看 “free” 那一个数字。

磁盘用df -h查看分区占用和挂载情况。某个分区满了之后,服务往往表现得很奇怪,日志写不进去、临时文件创建失败,但系统本身又没崩溃,这时df -h能快速定位是不是磁盘满了。查找某个目录占用多少空间用du -sh,比如du -sh /var/log就能看出日志目录总占用。

系统负载用uptime直接查看,它会显示过去1分钟、5分钟、15分钟的平均负载。负载并不是越低越好,它反映的是系统里处于运行和不可中断状态的进程数量均值。判断负载是否过高的标准,应该和CPU核数对照:负载持续超过核数,说明有进程在排队,系统可能过载;如果只是瞬时冲高又回落,往往不用太紧张。

6. 网络与远端:连通性检查、下载和文件传输

6.1 快速检查网络连通性和端口监听

排查网络问题,第一步永远是判断“能不能通”。ping可以用来测目标主机是否可达,但它测的是ICMP协议,这个协议在某些云环境里是被安全策略屏蔽的。如果ping不通,不一定代表服务不可用,还需要配合端口检查判断。

检查本机端口监听,我常用的命令是netstat -tlnp,它可以列出所有处于监听状态的TCP端口和对应的进程。比如你想确认Nginx是否正常监听80端口,执行netstat -tlnp | grep :80立刻就能看到。新版系统中也可以用ss相关命令替代,但核心思路一样,都是查看端口和进程的对应关系。

检查远程端口是否开放,可以用telnet <IP> <端口>或者用后面要讲的nc工具。这类检查在实际排障中的价值,是帮你快速区分问题出在哪一层,是网络层面不通、防火墙拦截,还是服务本身没起来。我通常的排查顺序是:先ping检查主机可达性,再检查本机端口监听,最后从另一台机器尝试连接目标端口,三步下来基本能锁定方向。

6.2 用curl、wget、scp和rsync完成传输任务

下载文件最常用的是curl和wget。wget偏下载工具,支持递归下载和断点续传,适合拉取整个站点资源。curl更强悍的是接口调试能力,它可以发送GET、POST等各类HTTP请求。比如你怀疑后端接口状态异常,直接curl -i http://127.0.0.1:8080/health,-i表示输出响应头,一眼就能看到HTTP状态码。

远程传输文件,经典组合是scp和rsync。scp适合小文件和一次性传输,用法跟cp很接近,只是路径变成了用户@主机:路径形式。例如scp localfile user@server:/data/就能把本地文件推到服务器的/data目录。rsync更适合大目录、增量传输,它只传有差异的部分,还支持断点续传。我同步一个上百GB的静态资源目录时,第一次全量,后面增量都非常快。

用scp或rsync时,默认会走SSH协议,所以就不要再额外引出一层所谓的“特殊通道”需求,正常SSH密钥配置好之后,这些命令就能直接工作。

6.3 与远端交互时的自我保护习惯

与远端交互,最重要的就是安全问题。第一个习惯是尽量用SSH密钥而不是密码登录,把公钥放到服务器的~/.ssh/authorized_keys里,之后ssh、scp、rsync就会变得很顺畅。第二个习惯是避免用root远程登录,即使需要管理员权限,也优先通过普通用户加sudo的方式完成。第三个习惯是留意命令的输出,特别是一些从远端拉取并执行的脚本,务必先看懂内容再执行,不要盲目地curl ... | sh,这是CEOs里最危险的一种习惯,也是我见过很多人中招的来源。

7. 管道、别名与个人工作流:命令组合真正的价值场

7.1 管道是“常用命令”之间最关键的粘合剂

管道符号|可以把前一个命令的输出接到后一个命令的输入。这个机制的意义,其实远大于“看起来方便”。它意味着你可以把多个简单工具组合到一起,解决一个复杂问题,而这个过程完全不需要编程。

我印象最深刻的一个实战例子,是线上排查某个接口响应突然变慢。当时的命令链是:tail -f access.log | grep "某个接口路径" | awk '{print $NF}'先实时跟踪访问日志,过滤出目标接口的请求行,提取出最后一个字段(响应耗时),结果很快看到延迟从几十毫秒跳到了几秒。如果没有管道,你要么手工复制日志,要么写个临时脚本,效率完全没法比。

另一个高频场景是分析历史日志。比如想知道过去一小时内访问量最大的IP,可以:grep "某个时间段" access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -n 10这里一共用了六个命令协作,任何一个单独拿出来都很简单,但组合在一起就变成了一个很实用的统计报表。这就是管道思想的威力:你不是在使用一条条孤立的命令,而是在组装一条处理流水线。

7.2 重定向与别名:把常用组合固化下来

输出重定向用>和>>,前者覆盖写入,后者追加写入。日志采集时经常用command >> file.log 2>&1这样的写法,把标准输出和标准错误都追加到同一个日志文件。这里的2>&1是把错误输出重定向到标准输出,这样报错信息也会被记录到日志里。很多脚本跑完看不出问题,就是因为只重定向了标准输出,错误信息全丢在终端上没人看到。

别名alias可以用来给长命令起短名字。比如我长期维护的服务器上有多个Tomcat实例,我会在~/.bashrc里写上:alias logs='cd /var/log/tomcat && tail -f catalina.out'以后直接输入logs就能跳到目录并实时查看日志,节省了大量重复输入。注意,别名只对当前shell有效,想要永久生效,必须加到~/.bashrc或者~/.bash_profile里,之后用source ~/.bashrc重新加载配置。

7.3 我长期保留的几个组合习惯

最后分享几个我长期保留的组合习惯,你可以直接借鉴。

第一,任何危险操作之前先“打印预览”。比如打算批量删除文件,先执行find /data -name "*.log" -mtime +30看有哪些文件,确认无误后再在命令末尾追加-delete。第二,查看端口和进程对应关系时,用netstat -tlnp | grep而不是netstat -a,因为-a输出太多,过滤后再看才高效。第三,写脚本时涉及路径都使用变量,并在脚本开头加set -eu,前者让未定义变量报错,后者让脚本出错即停,避免“看起来执行完了其实每一步都错了”的情况。

如果你深入使用一段时间,会发现这些命令本身并不神秘,真正有价值的,是你在大大小小的故障里反复磨出来的那套“先看什么、再查什么、最后怎么做”的决策流程。包括我自己,也不敢说把每条命令都背全了,但凡是上述提到的高频组合,我都会把它们按场景分类存进自己的命令笔记,遇到类似问题时直接调用、调整参数即可。这才是“常用的Linux命令”最有价值的打开方式。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进