说实话,每次有朋友跑来问我“Linux命令记不住怎么办”,我都能猜到他们背后的困境:买了一本几百页的《Linux命令行大全》,翻到第三十页就放弃了;或者照着教程敲了两天命令,一关终端全忘光。这套路我太熟了。今天这篇不是什么命令字典,我想用Ubuntu这个最常见的发行版,把日常真正高频的Linux命令串成一套能直接用的“做事方法”。如果你刚接触Linux,或者只会开机、关机、打开浏览器,这篇文章会帮你省掉至少两个月摸索时间;如果你已经用了一段时间,但总在权限、进程、网络排查上卡壳,这里写的问题排查思路也能给你一些参考。
我接下来的写法不会按“文件命令、磁盘命令、网络命令”这种百科式分类,而是按你实际会遇到的问题场景来走:找不到文件怎么办、磁盘快满了怎么办、服务突然挂了怎么看、网页打不开怎么查。每个场景里出现的命令,我会顺手解释它背后的逻辑——理解逻辑比背命令重要得多,理解了之后,忘了具体参数你也能靠--help和man自己捡起来。
1. 学Ubuntu命令前,先把Windows的思维习惯卸下来
好多新手在Ubuntu上碰壁,不是因为记性差,而是因为在用Windows的思路用Linux。这个点没转过来,后面学什么命令都觉得别扭。
1.1 为什么“图形界面好用”的思路在Linux上行不通
我自己刚接触Linux那会儿也犯过同样的毛病:明明有桌面环境,为什么非要去敲命令?后来被现实教育了——图形界面适合你“知道大概在哪、但不需要精确控制”的场景,而Linux的日常管理工作,大量是“我要精确地做某件事”的场景。比如我要找出“昨天下午三点之后被修改、且大于200MB的所有日志文件”,图形界面点来点去,你半小时搞不定;命令行一条组合命令十秒钟出结果。
另一个更关键的原因:服务器上的Ubuntu是没有桌面的。你在云上租一台Ubuntu服务器,所有操作都只能通过SSH敲命令完成。就算你自己电脑上装了带桌面的Ubuntu,排查服务器问题时的命令操作逻辑,和你本地桌面是完全一致的。早一步放下“图形界面依赖”,早一步进入真正的Linux工作流。
1.2 理解“一切皆文件”比记住命令更管用
Linux有个设计哲学:几乎所有东西都被抽象成文件。你的键盘是文件,你的硬盘是文件,正在跑的进程是文件,网络连接也是文件。它们通常挂在/dev、/proc这些目录下面。这一下就能解释很多奇怪的问题:
- 为什么格式化U盘是往文件里写数据?
- 为什么查看CPU信息用的命令是
cat /proc/cpuinfo? - 为什么有些系统信息在
/sys目录里改一个文件就生效?
# 查看CPU信息,本质上就是读取一个虚拟文件 cat /proc/cpuinfo # 查看内存信息也一样 cat /proc/meminfo看到没有,Linux命令很多时候就是“对文件做操作”的简化表达。你理解了这层,再回头看ls是列出目录内容、cat是输出文件内容、vim是编辑文件内容,你会发现整个命令体系一下子有了抓手,不再是零散的一堆符号。
2. 文件和目录操作:从“找文件”和“看空间”两个场景说起
文件操作是Linux最基础的地基,这一节我不打算罗列cp、mv、rm每个参数的表格式清单——那些你随时可以用man cp查。我更想用两个高频场景,教你把这些命令真正串起来。
2.1 场景一:我知道文件在某个目录下,但不知道确切位置
这种情况太常见了。你下载了一个安装包、同事传给你一个配置模板、或者你记得昨天改过某个配置但忘了路径。最直接的办法是用find命令:
# 在整台机器上找文件名包含nginx的文件 sudo find / -name "*nginx*" 2>/dev/null # 在当前目录下,找最近一天内修改过的所有文件 find . -mtime -1 -type f # 精确找出所有大于500MB的文件,常用于排查磁盘占用 find / -type f -size +500M 2>/dev/null这里要说一个细节:2>/dev/null是什么意思?它在说“把报错信息丢到黑洞里去”。Linux下任何程序跑起来默认有三个通道,标准输入、标准输出、标准错误。你用普通用户身份去扫描/root或者/proc下的文件时,会看到一堆“Permission denied”的报错,如果不把标准错误重定向掉,日志会刷屏刷得你看不到真正的结果。这个思路在后面查日志、跑脚本的时候会反复用到。
如果觉得find每次全盘扫描有点慢,Ubuntu还带了一个locate命令,它靠的是系统维护的文件索引库,查询速度极快:
# 先更新索引库(一般装完系统后第一次使用前建议手动跑一次) sudo updatedb # 基于索引快速定位文件 locate nginx.conflocate的代价是索引不实时,新文件可能要等索引更新后才能查到。所以我的习惯是:日常随手查用locate,需要精确到时间、大小、权限这些条件时用find。
2.2 场景二:磁盘快满了,我该怎么快速找到占空间的元凶
服务器磁盘满是最常见的故障之一,很多服务表现为“突然卡死”或者“莫名其妙连不上”,一查才发现是根分区满了。排查思路分三步走:
# 第一步:看整体使用率,确定哪个分区紧张 df -h# 第二步:从根目录开始,一层层看哪个目录最大 sudo du -h --max-depth=1 / 2>/dev/null | sort -hr | head -20# 第三步:锁定到具体目录,再深入一层 sudo du -h --max-depth=1 /var 2>/dev/null | sort -hr | head -20这里有一个经验教训:du直接对根目录做全量扫描通常很慢,因为它要把所有子目录都遍历一遍,所以在生产环境我一般先扫第一层,锁定大目录后再往下钻,而不是一把梭直接扫到底。sort -hr是“按人类可读的数字排序并倒序”,head -20只取前20行,这俩是du的好搭档。
还有个容易被忽略的坑:在Linux里,删除文件并不一定马上释放空间。如果某个进程还握着这个文件的句柄(file descriptor),那你rm之后空间依然被占用着。遇到这种情况,需要先找到持有文件的进程,重启或结束它,空间才会真正释放。排查方式是通过lsof查看已删除但仍被占用的文件:
sudo lsof | grep deleted这个坑我踩过不止一次。删了一个上百G的日志文件,df -h一看使用率纹丝不动,当时以为是文件没删掉,折腾半天才发现是进程还开着句柄。把这招记住,以后能省不少事。
3. 权限体系:搞懂Permission denied,你才算入了门
如果你在Ubuntu上折腾两天,肯定见过这样的报错:Permission denied。很多新手第一反应是“系统坏了”,其实不是,是权限模型不允许你这么干。
3.1 读一下那串十位字符,别用背的,用看的
执行ls -l的时候,每行开头有一串像drwxr-xr-x的字符。这十位可以拆成四段:第一位表示类型(d是目录,-是普通文件,l是软链接),后面九位每三位一组,分别是“文件所有者”(user)、“文件所属组”(group)、“其他人”(others)的权限。每组里的rwx分别对应读、写、执行。
-rw-r--r-- 1 user user 1024 Jun 20 10:00 notes.txt上面这行的意思是:所有者user可以读写,但不能执行;同组的其他人只能读;其他所有人也只能读。注意这个文件也“没有执行权限”,所以哪怕你是所有者,也不能直接把它当脚本跑。
很多人学权限时死记chmod 755、chmod 644,但不知道数字哪来的。其实很简单:读是4,写是2,执行是1,加在一起就是一组权限的数值。7 = 4+2+1表示可读可写可执行;6 = 4+2表示可读可写;5 = 4+1表示可读可执行。755就是从高到低三个“身份”各自的权限值。这个编码逻辑只花一分钟就能记住,之后你再看所有权限相关的配置,一眼就能看懂。
3.2 我该什么时候用sudo,什么时候不该用
Ubuntu默认不给root配密码,日常管理用的是sudo,意思是“以管理员权限执行后面的命令”。sudo可以执行任何命令,但这不意味着所有命令都应该加sudo。一个常见的错误是,写文件写不进去就随手加sudo,久而久之你自己创建的文件的属主都变成root了,后续再用自己的账号去改又得加sudo,陷入死循环。
我的建议:
- 系统级操作(装软件、改系统配置、管理服务)用
sudo,这是正常的。 - 自己的项目、自己的配置,尽量不用
sudo。如果发现不用sudo操作不了,先检查是不是目录权限不对,而不是无脑上sudo。 - 修改任何系统文件前,先备份一份。比如改
/etc/nginx/nginx.conf,我会先复制一份nginx.conf.bak再动手。这不是胆小,是实战踩坑换来的习惯。
还有一种容易踩的权限坑是:你从网上解压了一个压缩包到当前目录,ls -l一看所有文件都是rw-r--r--,属主是某个你没见过的数字。这通常是压缩包里的文件带着它原来的属主信息,或者你用了sudo解压。解决办法是:
# 将当前目录及子目录的文件属主改为当前用户 sudo chown -R $USER:$USER /path/to/directorychown是改属主的,-R是递归处理子目录。这个命令在拿到别人给的项目包、迁移服务器数据时极其常用,学会了就不会再被“我没有权限编辑这个文件”卡住。
4. 系统状态与进程排查:CPU飙高、服务起不来该怎么看
很多人在Ubuntu上“用过”不少命令,但一遇到服务器异常就抓瞎,其实是因为缺少一套排查思路。这一节我讲两个高频故障场景的处理流程:CPU飙升查进程、服务起不来查状态查日志。
4.1 先学会用top和ps回答“谁在吃资源”
最简单的CPU监控命令是top。它像任务管理器一样动态刷新,显示CPU、内存占用情况,以及当前占用最高的进程列表。在top界面里按P可以按CPU占用排序,按M按内存排序。如果你想只看某个进程的情况,可以用top -p 进程PID或者直接在top界面里按f然后筛选。
top适合动态观察,但如果你想“定性”地知道某个程序当时在干嘛,用ps加参数组合更清晰:
# 查看所有进程,并显示详细格式 ps aux # 只看与nginx相关的进程 ps aux | grep nginx输出的每一列都值得扫一眼:%CPU是CPU占用,%MEM是内存占用,PID是进程编号。查到了可疑的高占用进程,下一步就是决定要不要处理它,以及怎么处理。普通用户只能kill自己的进程,要结束别的用户的进程就需要sudo:
# 先尝试温和地结束进程(相当于通知它“你可以收工了”) sudo kill PID # 过5秒还没退,再用强制结束 sudo kill -9 PID我建议把kill和kill -9分开看待。kill默认发的是TERM信号,进程收到后有“整理现场”的机会,很多服务可以正常落盘、关闭连接。kill -9则是直接干掉,进程没有机会做任何清理,有可能留下临时文件或数据不一致的问题。所以能先kill就先用温和的方式,实在不行再上kill -9,这算是一点实战小原则。
4.2 服务起不来:从systemd到日志的排查链路
现代Ubuntu用systemd管理系统服务。和之前用脚本管理服务的方式不同,systemd给每个服务都定义了一套运行规则,并提供了一套相对统一的操作命令:
# 查看服务运行状态 sudo systemctl status nginx # 启动、停止、重启服务 sudo systemctl start nginx sudo systemctl stop nginx sudo systemctl restart nginx # 设置开机自启 sudo systemctl enable nginx这些命令不难,真正难的是“服务起不来”之后的排查。别光盯着status输出的那几行,它只是告诉你一个结论,真正的原因通常藏在日志里。查看服务日志的命令是:
# 查看某个服务的全部日志 sudo journalctl -u nginx -n 50 # 实时滚动查看最新日志,排查问题时非常有用 sudo journalctl -u nginx -f这里要说一个排查的顺序感:先看status有没有报错,再看journalctl里拉出来的日志从头到尾读一遍。日志会告诉你是端口被占了、配置文件写错了、还是缺少某个依赖。很多人一到这个环节就慌,其实只要冷静把日志里“error”“fail”相关的行用grep筛出来,大部分问题都能定位。
另外一个常见的坑是端口冲突。你的服务明明配置好了,但systemctl start nginx就是报失败,这时大概率是80端口被别的程序占用了。查端口占用可以用:
# 查看当前所有监听的TCP端口,以及对应的进程 sudo ss -tlnp这里-t看TCP,-l只显示监听状态,-n用数字显示端口,-p显示进程信息。看到80端口被某个PID占着,配合ps aux | grep 这个PID或者ll /proc/进程号/exe,就能知道是谁抢了端口。解决方式很灵活:要么改新服务的端口,要么停掉占用的进程。
5. 网络排查四板斧:连不上、解析不了、端口不通怎么查
网络问题排查,说复杂很复杂,说简单其实有一套固定的套路。我给你拆成四步,每一步对应一类命令。这四步跑完,常见的网络故障基本都能定位到方向。
5.1 ping不通不一定是网络断了
很多人第一反应就是ping,但ping不通的原因太多了:对端禁ICMP、你本地没配网关、路由不通、甚至只是对端域名解析出的IP变了。所以ping更像一个“初步探测”,不能用它一锤定音。
# 测试能不能连通一个IP或域名,并持续显示延迟 ping -c 4 example.com如果ping不通,下一步先检查自己的IP和默认路由:
# 查看所有网卡和IP地址信息 ip a # 查看默认路由 ip routeip a的输出里,eth0这类是网卡名,下面那串inet 192.168.x.x/24是这个网卡的IP地址。如果这串IP是空的,说明网卡根本没拿到地址,需要检查网络配置或DHCP。ip route里如果看不到default via那一行,说明没有默认网关,外网肯定出不去。
5.2 端口通不通,用ss和curl判断
网络上有一个经典问题:“我ping通了对端,但就是连不上它的某个端口。”这种情况就得绕开ping,直接测试端口和协议:
# 查看本地监听端口 sudo ss -tlnp # 测试远程某个端口是否开放(可以临时用nc) nc -zv 192.168.1.10 22如果端口未开放,但你确认服务在跑,那八成是防火墙拦了。Ubuntu默认的防火墙管理工具是ufw:
# 查看防火墙状态和规则 sudo ufw status # 允许某个端口的访问 sudo ufw allow 8080注意调整防火墙规则后,最好验证一下规则是否真的生效。我遇到过写好了规则但没重启导致没生效的情况,所以每次改完防火墙,都会顺手再ss -tlnp确认服务端口在监听、再用外部机器实际连一次。
5.3 域名解析出问题,别急着怪DNS
有时候你访问某个域名打不开,但访问IP地址却是好的,那就是DNS的问题。Ubuntu下的域名解析查询可以用dig,如果没有安装可以先装一下:
# 查询域名对应的IP dig example.com # 指定使用哪个DNS服务器查询 dig @8.8.8.8 example.com如果dig显示能解析出IP,但浏览器还是打不开,可以再试试curl -v看整个HTTP请求过程卡在哪一步:
# 显示完整的HTTP请求和响应细节 curl -v http://example.comcurl -v这个命令是我排查网页类问题的首选。它会把每一步都打出来:DNS解析、TCP连接、TLS握手、HTTP请求、响应头。你能看到到底是“解析失败”“连不上服务器”“还是收到了但内容不对”,不会瞎猜。
6. apt装软件不翻车,这些小细节值得留意
Ubuntu下装软件最常用的是apt,它解决了一个上古难题:“装A之前要先把B装好,而装B之前又要先装C。”apt会自动把依赖关系处理掉,这体验比Windows下一堆“缺少DLL”舒服太多。
6.1 日常安装、升级、卸载的标准姿势
装软件前的第一步永远是更新软件源索引。这个概念很多新手理解不了:apt update并不是升级软件,而是从软件源拉取最新的可用软件列表。更新完索引以后,apt才知道哪个包可以装、哪个包有新版。
# 更新软件源索引 sudo apt update # 搜索想装的软件 apt search nginx # 查看软件包详细信息 apt show nginx # 安装软件(-y表示自动确认) sudo apt install -y nginx # 升级所有可以升级的包 sudo apt upgrade # 卸载软件但保留配置文件 sudo apt remove nginx # 卸载软件并清除配置文件 sudo apt purge nginx一个容易被忽略的习惯:不要只是apt install然后就不管了,定期apt update && apt upgrade很重要,安全补丁基本都在这些升级里。
6.2 软件包冲突和依赖问题的兜底方案
apt装多了,偶尔会遇到“以下软件包有未满足的依赖关系”或者“您在运行apt时使用了不稳定的软件源”之类的报错。这种情况先别慌,也别听网上瞎说一通apt remove重装,先试试下面几个操作:
# 修复依赖关系 sudo apt --fix-broken install # 清理缓存里的损坏软件包 sudo apt clean # 再次更新索引 sudo apt update如果某个源总是出问题,还可以检查/etc/apt/sources.list和/etc/apt/sources.list.d/下面的源配置文件,把可疑的源注释掉或移除。实在不行,apt还有自动移除不再需要的依赖包的选项:
# 自动卸载不再需要的依赖 sudo apt autoremove这里有个非常有用的原则:在动系统里已有的软件包之前,尽量搞清楚它为什么存在。有些是别的软件自动带上的依赖,有些是你自己当初装完忘了。擅自卸载可能导致某个服务起不来,别为了省几百兆磁盘去强行autoremove一个不确定的包。
另外,很多软件不在Ubuntu默认的源里,需要添加PPA或者导入官方源的GPG密钥。这个操作风险比默认源高,因为它等于你选择了信任一个第三方维护者。我的建议是:优先从官方源装,装不到了再去官方文档里找他们的仓库地址,而不是随便从搜索引擎复制一段添加源的命令就跑。加了不信任的源,等于把自己服务器的软件供应链交了一部分给别人。
7. 文本处理组合拳:日志分析中的grep、awk、sed
命令行的另一个巨大优势是文本处理。日常排查问题,绕不开从日志、配置文件、命令输出里提取信息。Linux提供了三个文本处理三剑客:grep、awk、sed。它们各自擅长不同的活儿,组合在一起堪称“日志分析流水线”。
7.1 grep:不光是“筛行”,语法细节才是关键
grep是简单的“在文本中搜索并输出匹配的行”。但这个命令的细节其实不少:
# 在一条命令的输出里筛选关键字 ps aux | grep nginx # 忽略大小写搜索 grep -i error /var/log/nginx/error.log # 把匹配行的上下文也打出来,前后各5行 grep -C 5 "timeout" /var/log/syslog # 递归搜索整个目录 grep -r "listen" /etc/nginx/如果希望匹配更灵活,可以用扩展正则表达式,这就要用到grep -E,等于把它当成egrep用:
# 同时匹配error和fail两种关键字 grep -E "error|fail" /var/log/nginx/error.loggrep能解决的是“找到相关行”,但很多时候你找到了几百行,还得做下一步处理:按某一列排序、去重、统计数量,这就轮到awk出场了。
7.2 awk按列处理,sed按行替换
awk最常用的一种场景是按分隔符切分内容,提取特定列。比如日志里每行都用空格隔开,你想提取第五列的时间戳,就可以:
# 输出每行的第一列和第五列 awk '{print $1, $5}' /var/log/nginx/access.log还可以直接在awk里做统计。比如统计访问量最高的前十个IP:
# 按第一列(通常是IP)做分组计数并排序 awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10这一行命令把awk、sort、uniq串在一起,在没有任何监控工具的情况下也能迅速回答“谁在频繁访问我的网站”这个问题。很多安全上的异常扫描,最初就是这么看出来的。
sed则更擅长做“查找并替换”。它的典型用法是把一段文本里的某个旧参数替换成新参数:
# 把文件里所有"old.dev"替换成"new.dev",不影响原文件 sed 's/old.dev/new.dev/g' /tmp/config.txt # 真正修改原文件(-i参数) sed -i 's/old.dev/new.dev/g' /tmp/config.txt每次用sed -i之前,我几乎都会先想一下有没有备份。因为-i是直接改原文件,一旦正则写错了,文件内容可能被“原地”改乱。稳妥的做法是先在屏幕输出上验证一遍,去掉-i跑一次,确认结果没问题,再真正改文件。
7.3 管道思维:把单条命令的输出变成下一条命令的输入
上面几个命令之所以能组合,靠的是Linux的“管道”机制,用|把一个命令的输出直接接到下一个命令的输入里。这个机制看起来简单,但它彻底改变了操作方式。Windows下你没得选,只能靠图形界面的菜单一条条做;Linux下你可以把“找文件 + 筛关键字 + 按列统计 + 排序取前几条”串成一行,秒出结果。
我举个例子。排查问题时经常需要实时看日志,但只想看错误相关的、并且不想让日志刷满屏幕:
# 实时跟踪日志,并只输出包含error的行 tail -f /var/log/syslog | grep error这个组合里,tail -f负责“持续输出新日志”,grep error负责筛选。如果日志刷得太快,你还可以再加一个head或者重定向到文件,避免把终端冲爆。这种“流水线”式的思维方式,才是命令行和图形界面最大的区别——也是你能越来越熟练的核心动力。
8. 综合实战:把上面的命令串起来,定位一个“Web服务响应缓慢”的问题
前面讲了不少命令,但它们如果分开来看,还是碎片化的。我把它们放进一个典型的实战场景里:你的Ubuntu服务器上跑着一个Nginx网站,但客户反馈页面打开特别慢,你只有SSH终端,没有图形界面。接下来按顺序走一遍排查流程。
8.1 第一轮定位:系统整体状态优先于业务日志
第一步,先看系统整体情况,判断是资源耗尽还是服务本身的问题:
# 查看CPU、内存、负载情况 top -bn1 | head -20top -b是批量模式,适合一次性输出后交给管道处理。注意看整体负载(load average)和CPU占用率。如果CPU占用接近100%,再往下看哪几个进程占用最高;如果内存几乎用满,看是哪个进程占了大头。
第二步,看磁盘是否吃紧。磁盘满会拖慢所有写操作,最终让服务变得像“死机”一样:
df -h如果某个分区使用率超过90%,就要重点排查那个分区里的大文件,做法跟前面讲的一样,用du逐层往下钻。
8.2 第二轮定位:进程、端口和日志三查
系统整体没问题,就把焦点收到Nginx服务上:
# 服务状态 sudo systemctl status nginx # 端口是否在监听(确认服务真的在跑) sudo ss -tlnp | grep :80 # 看看实际的错误日志 sudo tail -n 100 /var/log/nginx/error.log如果status显示服务正常,端口也正常,但页面还是慢,问题可能在应用后端。再看看有没有大量排队的连接、有没有可疑的进程在频繁写日志。一个非常常见的坑是日志文件过大——如果access.log到了几个G,磁盘IO会被拖垮。这时候用ls -lh看一眼日志大小,如果太大就及时轮转或清理。
8.3 第三轮:日志分析与慢请求定位
如果Nginx直接返回很慢,可以查一下慢请求。Nginx的access.log里通常有响应时间字段。先用tail看最近5分钟的新日志:
tail -n 200 /var/log/nginx/access.log发现有些请求耗时特别长,就用awk把所有请求耗时提取出来,排序后看最慢的几个:
# 假设第9列是响应时间(具体看日志格式),找出最慢的20个请求 tail -n 5000 /var/log/nginx/access.log | awk '{print $9}' | sort -nr | head -20再看这些慢请求对应的URL和IP,进一步追踪是哪个路径、哪个来源的请求。如果慢请求全部指向一个API接口,那就是应用层的问题;如果慢请求分布很随机,则可能是网络或DNS的问题。
这套流程跑下来,每一步都有一个明确的结论:“系统资源没问题”“服务在跑且端口正常”“日志里有规律”“问题集中在哪里”。绝大多数服务异常都不需要什么高级监控平台,先靠这几个命令把问题范围缩小,再决定要不要升级到更重的工具。
写在最后
写这篇里我一直在克制一件事:不把命令字典搬过来。网上满大街都是那种一页几百个命令的仓库,你真照着敲一遍,会发现能记住的没几个。Linux命令学习的本质,是建立一套“遇到问题→想清楚要做什么→选择合适的工具→组合命令”的思维方式。命令忘了就去man、去--help、去搜,这完全正常;但你心里得有一条排查问题的路,知道往哪个方向走。
如果你刚在Ubuntu上起步,我建议你从今天开始做一个自己的“命令笔记”,不是抄别人整理好的,而是记录你实际用过、解决过实际问题的操作。每当你成功解决了“磁盘满了”“服务挂了”“网页打不开”这类问题,就把当时敲过的命令和处理思路记下来。用不了几次,你会发现自己的命令库越来越顺手,而且每个命令都带有你自己的实战场景,想忘都难。