简介:一份整合Ubuntu新手入门、进阶优化与实战项目的系统指南,面向初次接触Linux的用户及希望提升开发效率的开发者。资源包为单个docx文档,大小仅21KB,内容却相当扎实:从系统安装与初始化、终端和软件管理入手,包含基础安装、分区方案推荐、首次配置和常用apt命令;接着讲解开机加速、资源监控等性能调优技巧,再进入Docker容器化开发、Python虚拟环境搭建,并配套LAMP网站部署、自动化脚本、Docker Compose编排和Harbor私有仓库等可操作案例。文档还整理官方文档、社区教程及常见问题避坑方法,覆盖依赖冲突处理、NVIDIA驱动自动安装等实际痛点,并延伸至AI开发环境与边缘计算场景。已有1126人学习下载,可作为日常操作手册或开发实践参考,按需选读即可快速落地。
1. Ubuntu 不是装完就完事:新手到能干活之间隔着几道坎
很多人的 Ubuntu 使用史开始于一次安装实验。装完系统、进入桌面,觉得一切正常;等到需要装软件、挂磁盘、看日志、部署服务时,才意识到这套系统和熟悉的图形界面操作系统是两套思维:软件要用包管理器自己拉,权限要用命令行自己给,服务要写配置自己管。这篇文章就用来补上这几道坎。
我从版本选型、分区规划、装后初始化讲起,再走一遍包管理、权限、日志这三条日常主线,随后进入 systemd 和 Shell 效率这类进阶操作,最后用一个文件归档清理的模拟项目X,把虚拟环境、定时任务、日志验证串成一条能动手复现的完整链路。新手照着做能少走弯路,熟手可以直接跳到对应章节查命令和边界条件。
2. 先选对版本再动手:版本选择、分区规划与装后初始化
在装系统之前,先花十分钟想清楚这台机器接下来干什么用。做开发机、办公机和做服务器,选型完全不同。常见做法是先定形态、再规划分区、最后做初始化,这个顺序反了,返工成本会很高。
2.1 桌面版还是服务器版:两种形态的适用边界
选型的第一件事是判断这台机器需不需要图形界面。有显示器、要写代码、要开浏览器、要跑 GUI 调试工具,选桌面版;机器放在机柜里或者只通过 SSH 连接,选服务器版。这个边界可以打破:桌面版完全可以跑服务,服务器版也能装回桌面,但无头机器装图形栈只会白白占内存和带宽,还多一倍的更新面。我自己常用的原则是「能不用图形界面就不用」,省下来的内存留给编译和容器更划算。
| 对比项 | 桌面版 | 服务器版 |
|---|---|---|
| 图形界面 | 自带完整桌面 | 默认无桌面 |
| 适用场景 | 个人开发、GUI 调试、日常办公 | 云主机、后台服务、无头机器 |
| 资源占用 | 图形栈常驻,内存开销高 | 低,省下的内存给业务 |
| 上手难度 | 新手友好 | 需要熟悉命令行 |
版本节奏也影响选择。LTS 版本维护周期长、更新保守,适合绝大多数场景;短期版本能更快获得新内核和桌面特性,但维护期短,不适合长期部署。我的建议是:不管新手老手,日常使用选当前最新的 LTS 版本,服务器则只考虑 LTS。装系统前可以在 Live 环境里看一眼磁盘布局,这是后面分区规划的依据:
lsblk这条命令列出块设备、分区大小和挂载点。U 盘启动的 Live 环境里,它显示的设备名和装完系统后一致,提前截图便于后面核对。资源方面最权威的不是第三方教程,而是官方安装指南;系统装好后,man 手册和/usr/share/doc目录里每个软件包都带有自己的文档,遇到问题先查这两处,比在网络上碰运气更靠谱。
2.2 分区规划:系统盘留多少、swap 该不该单独分
分区方案不用追求复刻网上任何「最佳实践」,按重装场景倒推即可。如果希望重装系统后/home里的数据还在,就把/home单独拆出来;如果只是练手机,分一个/加一个 swap 也就够了。UEFI 引导的机器,安装器会自动创建 EFI 分区,一般不需要手动干预。
常见的分配逻辑是:根分区/至少留 50GB,后续装开发环境和容器镜像才不至于很快报警;swap 按内存大小给,物理内存 16GB 以内时 swap 给到和内存等量,内存更大的机器 swap 给 8-16GB 足够。如果以后要休眠到磁盘,swap 要大于内存,但桌面机默认不开休眠,不用提前预留。机械硬盘上 swap 单独放一个分区读写更稳定,固态硬盘则不用在意位置。
安装完成后的第一件事,是用下面三条命令验证挂载情况:
lsblk df -hT sudo blkidlsblk看卷组和设备对应关系,df -hT看实际使用率和文件系统类型,blkid看 UUID。UUID 后面写 fstab 或者挂载新磁盘时用得最多,建议截图存档。双系统环境下,两套操作系统的时间经常对不上,这是硬件时钟默认标准不一致导致的,不属于硬件故障,在系统里把本地时钟设为 RTC 标准即可,命令留在避坑章里讲。顺便提醒一句:安装器里选择手动分区后,目标磁盘上的数据会被清空,动手之前先把重要文件备份到独立存储上,这是最容易后悔的一步。
2.3 装完系统后的第一步:全量更新、确认驱动、装基础工具
新装的系统往往带着发布当天的软件索引,几个月后第一次开机,仓库里早就不是这批版本了。所以第一步永远是先刷新索引再执行升级,这两步分开写是有原因的:update只更新软件列表,upgrade才真正下载安装新版本。一口气跑完,后面装别的包时依赖冲突会少很多。
sudo apt update && sudo apt upgrade -y sudo apt install -y curl git vim htop ca-certificates sudo ubuntu-drivers devices第二条命令装的是高频基础工具:curl 测接口和下载,git 拿代码,vim 应急改配置,htop 看进程,ca-certificates 是后续很多 HTTPS 依赖的前置包。第三条命令会列出当前机器可用的驱动,如果机器只是办公和写代码,驱动可以跳过;如果需要跑渲染、训练或者大型图形工具,就装它推荐的驱动。装完驱动后先不要急着重启,用lsmod查一下模块是否加载成功,确认没有报错再重启,能避开后面「图形界面进不去」的经典翻车点。
系统初始化的最后一步,我习惯顺手校正时区。日志里的时间错位会干扰排障判断:
sudo dpkg-reconfigure tzdata交互界面里选好所在城市即可。这一章做完,系统已经有了一个相对干净、可长期使用的基础状态,接下来进入日常使用频率最高的三条主线。
3. 包管理、权限和日志:把三个黑匣子逐个打开
日常使用中你打交道最多的是 apt、权限和日志。这三个概念理解到位,大部分系统问题自己就能定位,不需要每次求助别人。这一章我把每个黑匣子拆开,给出一组可直接复制的命令,并说明每条命令在什么场景下用。
3.1 apt 安装、卸载与依赖修复:软件安装的正规军与游击队
apt 是包管理的前端,dpkg 是底层工具。绝大多数软件优先走 apt,因为它会自动处理依赖;装不上的.deb包用 dpkg 硬装,依赖出问题时再用apt --fix-broken收尾。我见过不少新手遇到依赖报错就到处搜教程手动删文件,其实 apt 内置的修复机制能解决大部分问题。
sudo apt update sudo apt install -y htop sudo apt remove htop sudo apt purge htop sudo apt autoremove sudo apt --fix-broken install sudo dpkg -i 某个软件包.deb apt-cache search 关键字remove只卸载程序,保留配置文件,适合临时移除后还想装回来的场景;purge连配置一起清掉,适合彻底不要了;autoremove清理不再被依赖的孤立包,能让系统保持干净;--fix-broken install是遇到依赖损坏时直接补装缺的包。dpkg -i装本地.deb时如果提示缺依赖,后面跟上apt --fix-broken install就能把依赖补齐。apt-cache search是安装前查包名是否存在的标准做法,比在网页上搜索准确得多。
这里有个常见误用要提醒:出现依赖错误时,不要直接删/var/lib/dpkg目录下的文件。那是包管理的索引数据库,删了之后所有已装软件的记录都会丢,系统会处于一种更糟糕的「半坏」状态。正确顺序永远是先dpkg --configure -a,再apt --fix-broken install。
3.2 用户权限与目录权限:为什么老是被 Permission denied
权限问题几乎都是同一个逻辑:当前用户对目标文件或目录没有读、写、执行的权限。Ubuntu 里sudo是逐条命令提权,不是永久切到 root,很多人把这个概念搞混,才会出现「明明加了 sudo 还是报错」的情况。先看清当前身份和文件属主,问题往往就解开了一半。
whoami ls -l /etc/shadow sudo usermod -aG sudo 某用户 sudo chown -R 某用户:某组 某目录 sudo chmod 755 某文件whoami确认当前用户;ls -l输出第一列的十位字符里,第一个字符是文件类型,后面三组字符分别代表属主、属组、其他人的读写执行权限,Permission denied 的原因基本都在这里。usermod -aG sudo 某用户给用户加管理员组,注意-a不能丢,丢了会把用户从已有组里踢走。chown -R用于目录归属错乱,比如新挂载的硬盘默认属主是 root,需要递归变更给普通用户。chmod 755是常用可执行权限:属主可读写执行,其他用户只读和执行。不要随手对/home整个目录递归chmod,会把所有用户的配置文件权限改坏,这种问题排查起来非常痛苦。
3.3 进程与日志:系统卡了先别重启,先看这三样
重启确实能治很多病,但好习惯是先留下证据再动手,否则下次复现时还是不知道根源。常见做法是:先看资源占用,再看系统日志,最后才决定重启还是定位。这一步能覆盖八成问题的排查路径。
htop ps aux --sort=-%mem | head -15 journalctl -xe journalctl -u 某服务 -n 50 --no-pager dmesg | tail -30htop交互式看 CPU 和内存占用,按 F6 可以排序;ps aux --sort=-%mem | head -15用纯命令输出内存占用最高的前 15 个进程,适合在 SSH 会话里快速判断。journalctl -xe查看最近的系统错误,-u 某服务指定服务名,-n 50控制行数,--no-pager避免输出卡在 less 里。dmesg | tail -30看内核日志,磁盘报错、驱动加载失败、文件系统异常通常都在这里。如果 htop 显示内存占满、swap 持续上涨,而 dmesg 里又有 I/O 报错,基本可以判断是内存不足导致磁盘换页,方向对了再动手。
4. 进阶操作:systemd 服务托管、Shell 效率与资源瓶颈定位
过了日常主线,进阶的核心是「把自己的程序变成系统的一部分」,以及「用更高效率的方式和系统交互」。这里挑了三条最常用且可复现的进阶路径:用 systemd 托管自写服务、用 alias 和 Shell 函数缩短高频命令、用资源定位命令替代「凭感觉优化」。
4.1 用 systemd 写一个自启服务:开机运行、崩溃重启都交给它
systemd 是现在 Linux 主流的初始化系统,负责开机启动、服务依赖和崩溃恢复。自己写的服务单元文件放在/etc/systemd/system/下,这样不会被软件包升级覆盖。下面是一个 Python 常驻服务的单元示例:
[Unit] Description=某模拟项目X服务 After=network.target [Service] User=某用户 WorkingDirectory=/home/某用户/app ExecStart=/usr/bin/python3 /home/某用户/app/main.py Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.targetAfter=network.target表示网络就绪后再启动,避免脚本启动时拉不到远端资源;User用最小权限账号运行而不是 root,这是安全底线;Restart=on-failure只在上次退出异常时拉起,always则无论什么原因退出都重启,适合关键常驻服务但可能造成反复重启的死循环,所以我在示例里选on-failure。改完文件必须重载配置再启用:
sudo systemctl daemon-reload sudo systemctl enable --now 某模拟项目X服务 systemctl status 某模拟项目X服务 journalctl -u 某模拟项目X服务 -n 30 --no-pagerenable --now是启用开机自启并立即启动,分开写成enable再start效果一样。启动失败时先看status,再通过journalctl -u 服务名拉日志,几乎都能定位到原因。如果只是微调参数,可以用systemctl edit做局部覆盖,不必改原始单元文件。
4.2 alias 与 Shell 函数:把高频操作压成一次输入
~/.bashrc在交互式 Shell 启动时加载,alias 和函数都适合放在这里。需要注意一个边界:alias 只在交互命令里生效,写进脚本不会展开。所以脚本里要用完整命令,而交互终端里可以尽情缩短。下面是我常用的几行配置:
alias ll='ls -alF' alias update='sudo apt update && sudo apt upgrade -y' alias gs='git status' service_log() { journalctl -u "$1" -n "${2:-50}" --no-pager; } export PATH="$PATH:$HOME/.local/bin"单引号包裹命令体,防止定义时变量过早展开;函数service_log接收两个参数,第二个参数不传时默认-n 50,这样查不同服务日志不用重复敲命令。最后一行是追加 PATH 的安全写法,这里强调一下,export PATH="$PATH:新路径"是在原值后面追加,直接写export PATH=新路径等于覆盖整个 PATH,能把所有命令搞丢,这是第 5 章要细讲的一个坑。修改完.bashrc后执行source ~/.bashrc立即生效,或者重新登录也可。
4.3 磁盘与内存定位:用数据而不是感觉判断瓶颈
系统变慢时,新手的第一反应是「换个配置更好的机器」,但很多时候只是日志占满磁盘或者某个进程内存泄漏。先用数据定位,再决定要不要花钱升级,这个习惯比任何优化技巧都重要。
df -hT du -sh 某目录/* free -h vmstat 1 5 ps aux --sort=-%mem | headdf -hT看文件系统使用率,-T带文件系统类型,能认出 tmpfs 和 overlay 这类特殊挂载;du -sh 某目录/*直接算出目录下每个子目录的占用,定位哪个目录在悄悄吃盘;free -h看内存总量和 swap 用量。vmstat 1 5每秒采样一次,连续 5 次,重点关注si和so两列,只要持续非零,说明物理内存不足、系统在大量换页。最后再用ps aux --sort=-%mem确认是谁占用了内存,定位到具体进程后再决定是重启服务还是调整配置。
5. 项目实战前常见问题与避坑:四条值得背下来的翻车记录
这一章是「先固证再操作」原则的延伸。下面四条是我身边反复出现的高频坑,每条按现象、原因、解决、预防展开。你不需要全记住,但遇到类似现象时能翻回来对照,就已经省下半天时间。
5.1 装完显卡驱动后循环登录或图形界面进不去
现象:输入密码后黑屏闪回登录界面,或者能进桌面但花屏;有时是内核更新之后突然发生的。原因:内核升级后驱动模块和当前内核版本不匹配,或者同时装了不同来源的驱动包导致模块冲突。解决:按 Ctrl+Alt+F2 切到 tty 登录,停掉图形会话再做处理:
sudo systemctl stop gdm3 sudo apt list --installed | grep -i 驱动 | grep -v lib sudo apt purge 查到的驱动包先停掉 gdm3,避免驱动卸载过程中图形会话反复拉起;再列出已安装的驱动包,确认包名后purge。重新安装时用系统推荐的版本,装完先用lsmod验证模块加载再重启。预防:没有显卡计算需求时不装闭源驱动;有需求时用 DKMS 管理模块,让驱动自动适配新内核。
5.2 /var/log 和 journal 日志把根分区吃满
现象:df -h显示根分区使用率 100%,服务报no space left on device,但自己没装过什么大文件。原因:systemd-journald 默认不限制日志体积,长期运行的服务的输出会无限积累,把/var/log和 journal 空间吃满。解决:
journalctl --vacuum-size=200M sudo systemctl restart systemd-journald df -h /--vacuum-size=200M把历史日志压缩清理到 200MB 以内,restart 让新配置生效。预防:编辑/etc/systemd/journald.conf,设置SystemMaxUse=500M,改完后重启 systemd-journald。这一步做一次,以后基本不会再被日志占满磁盘。
5.3 apt 锁占用与依赖损坏
现象:执行apt install时报Could not get lock /var/lib/dpkg/lock-frontend。原因:上一次 apt 进程没正常结束,或者两个终端同时跑了 apt。解决:先确认进程是否还在:
ps aux | grep apt sudo dpkg --configure -a sudo apt --fix-broken install确认没有残留 apt 进程后,用--fix-broken install修复。不要一上来就删/var/lib/dpkg下的锁文件,那只是最后手段,而且可能让状态数据库前后不一致。预防:同一时间只开一个终端跑 apt,长更新时耐心等完。
5.4 手滑把 PATH 改坏,命令全部 not found
现象:ls、sudo、apt 等命令全部提示Command not found,终端看起来「废了」。原因:在.bashrc里写了export PATH=某路径,把原 PATH 整体覆盖,忘了追加原来的值。解决:先用绝对路径应急,再修正配置文件:
/bin/ls export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # 修正 ~/.bashrc 中的 PATH 行后再 source第一行用绝对路径调起命令,第二行恢复基础 PATH,接着用/bin/vi把.bashrc里写错的export PATH=改成export PATH="$PATH:新路径"追加式写法,然后source ~/.bashrc。如果 sudo 也失效了,需要从恢复模式启动挂载根文件系统后修改文件。预防:修改.bashrc前先cp ~/.bashrc ~/.bashrc.bak留一份后悔药;写 PATH 一律用追加写法。
6. 用 Ubuntu 跑通一个定时归档任务:虚拟环境、systemd 定时器与验证闭环
6.1 创建项目目录与虚拟环境
先在用户目录建一个隔离环境,避免把系统 Python 环境弄脏。常见做法是每个项目单独建 venv:
mkdir -p ~/某归档清理Demo && cd ~/某归档清理Demo python3 -m venv venv source venv/bin/activate pip install --upgrade pipvenv是项目级隔离,激活后 pip 装的包只影响当前项目;退出环境用deactivate。系统 Python 环境保持干净,后面装系统级包时才不容易冲突。
6.2 写归档脚本
import datetime, pathlib, shutil def archive_old_files(base_dir: str, days: int = 30): base = pathlib.Path(base_dir) for item in base.glob("*"): if not item.is_file(): continue mtime = datetime.datetime.fromtimestamp(item.stat().st_mtime) if (datetime.datetime.now() - mtime).days >= days: target = base / "archive" / item.name target.parent.mkdir(exist_ok=True) shutil.move(str(item), str(target)) print(f"{item.name} -> {target}") if __name__ == "__main__": archive_old_files("/home/某用户/data", 30)脚本用glob遍历目录,stat().st_mtime取文件修改时间,超过设定天数就移到archive子目录。先手动跑一次,确认目录和文件符合预期,再交给定时器。
6.3 用 systemd 定时器托管并验证
# /etc/systemd/system/某归档清理.service [Unit] Description=某归档清理Demo [Service] Type=oneshot User=某用户 ExecStart=/home/某用户/某归档清理Demo/venv/bin/python /home/某用户/某归档清理Demo/archive.py # /etc/systemd/system/某归档清理.timer [Unit] Description=每天凌晨3点归档 [Timer] OnCalendar=*-*-* 03:00:00 Persistent=true [Install] WantedBy=timers.targetsudo systemctl daemon-reload sudo systemctl enable --now 某归档清理.timer systemctl list-timers 某归档清理.timer sudo systemctl start 某归档清理.service journalctl -u 某归档清理.service -n 20 --no-pagerType=oneshot适合一次性任务;Persistent=true让错过的计划在开机后补跑;OnCalendar=*-*-* 03:00:00是每天凌晨 3 点的 systemd 写法。验证闭环是:list-timers看到下次执行时间,手动start触发一次,再看 journalctl 输出和归档目录里的文件是否移动成功。我做完这类小任务后,养成了一个习惯:每次改完配置都跑一遍daemon-reload和status,确认服务真实状态而不是靠猜。项目先手动放一个测试文件验证,比定时器跑完再查日志省时间。这套流程从 Ubuntu 新手到日常运维都够用,希望帮到你。
本文还有配套的精品资源,点击获取