ubuntu系统安装软件的方法

方法一:APT 包管理器(最推荐,最常用)

这是 Ubuntu 的标准安装方式,直接从官方软件源下载并自动处理依赖关系。绝大多数系统级软件(包括 ROS 二进制包)都首选此法。

  • 核心操作

    bash

    复制代码
    # 1. 更新本地软件包索引(安装前必做)
    sudo apt update
    # 2. 安装指定软件
    sudo apt install <软件包名>
    # 3. 搜索软件包(不确定名字时用)
    apt search <关键词>
  • 卸载sudo apt remove <软件包名>

  • 优点 :自动解决依赖,卸载干净;缺点:版本可能相对旧一些。

方法二:安装本地 .deb 包(手动下载)

当软件官方只提供 .deb 安装包(如 Chrome、VS Code),或你需要安装特定版本的离线包时使用。

  • 核心操作

    bash

    复制代码
    # 1. 下载 .deb 文件(或通过 scp 上传)
    wget https://xxx.com/package.deb
    
    # 2. 使用 dpkg 安装(不会自动解决依赖)
    sudo dpkg -i package.deb
    
    # 3. 如果报依赖错误,必须执行以下命令修复依赖
    sudo apt --fix-broken install
  • 卸载sudo dpkg -r <包名>(包名不是文件名,需查 dpkg -l

  • 注意:务必执行第 3 步,否则软件可能无法运行。

方法三、二进制压缩包(tar.gz 绿色免安装)

适用场景

开发工具:JDK、Maven、Go、Redis 手动编译包、私服工具

操作流程

  1. 下载 tar.gz
  2. 解压到 /usr/local/
  3. 配置环境变量 PATH

示例

bash

运行

复制代码
tar -zxvf jdk-17.tar.gz -C /usr/local/
# 在 ~/.bashrc 添加环境变量
export JAVA_HOME=/usr/local/jdk-17
export PATH=$PATH:$JAVA_HOME/bin
source ~/.bashrc

缺点

无统一卸载命令,升级、管理全靠手动,不会注册 systemd 服务。

方法四:源代码编译安装(高度定制)

当你需要修改源码、使用最新未发布特性,或官方未提供二进制包时使用(如很多 ROS 功能包)。

  • 核心操作(以 C/C++ 项目为例):

    bash

    复制代码
    # 1. 安装编译工具链
    sudo apt install build-essential cmake git
    
    # 2. 进入源码目录,生成 Makefile
    ./configure   # 或 cmake .
    
    # 3. 编译(-j 指定并行核心数,加快速度)
    make -j$(nproc)
    
    # 4. 安装到系统路径(/usr/local 等)
    sudo make install
  • 卸载 :通常进入源码目录执行 sudo make uninstall(若支持);若不支持,需手动删除文件,较难彻底清除

  • 缺点 :编译耗时长,依赖手动解决,卸载麻烦。不建议系统级基础库使用此方法


法三(二进制压缩包) :里面的文件已经是 "机器码" (0和1组成的可执行程序),是开发者提前用编译器在特定系统(如 Linux x86_64)上编译好的。你解压后,电脑直接就能运行 里面的 bin 目录下的程序。

方法四(源码编译) :里面的文件是 "源代码".c.cpp.py 等人类可读的文本)。你的电脑完全看不懂这些代码,必须借助编译器(gcc/g++)在你的机器上现场翻译成机器码,才能运行。

复制代码
这个问题问到了根子上。理解这四种方法的**底层原理**,能帮你彻底明白软件"装没装"、"在哪"、"怎么跑"的本质。

我们可以从**"文件从哪里来"**和**"系统如何认识它"**两个维度,把这四层原理彻底讲透:

---

### 1. APT 包管理器:自动化"下载 + 安装 + 数据库登记"
APT 是 Ubuntu 的**上层包管理工具**,它的底层本质是调用 `dpkg`,但增加了**网络仓库**和**依赖解析**的能力。

- **底层原理**:
  1. **仓库索引**:`sudo apt update` 会从 `/etc/apt/sources.list` 里的服务器下载软件包列表(索引)。这个列表记录了所有软件包的名字、版本、依赖关系(比如 A 软件依赖 B 库)和校验值。
  2. **依赖解析**:当你输入 `apt install A` 时,APT 会读取索引,计算出为了装 A,还必须先下载 B 和 C(依赖树)。
  3. **下载与安装**:APT 从网上下载 A、B、C 的 `.deb` 文件,然后**依次调用 `dpkg -i`** 进行安装。
  4. **数据库记录**:安装成功后,APT 会在本地的 `/var/lib/dpkg/status` 数据库中**注册**该软件包的名字、版本和安装的文件清单。
- **本质总结**:它是一个**智能的下载器 + 依赖解算器**,把用户从手动找包、手动解决"缺少依赖"的苦海中解放出来。

---

### 2. 本地 `.deb` 包(dpkg):解压归档 + 执行脚本 + 写入数据库
`.deb` 文件本质上是一个**压缩归档包**,类似于一个"安装蓝图"。

- **底层原理**:
  1. **文件结构**:`.deb` 其实是一个标准的 `ar` 归档文件,里面包含三个压缩包:
     - `debian-binary`:声明包格式版本。
     - `control.tar.xz`:包含安装脚本(`preinst`、`postinst`)和元信息(包名、版本、依赖声明)。
     - `data.tar.xz`:**真正的"血肉"**,包含了所有要安装的文件(如 `/usr/bin/xxx`、`/etc/xxx`)。
  2. **安装过程(`dpkg -i`)**:
     - **解压**:把 `data.tar.xz` 里的文件直接**解压到系统的根目录 `/`** 下(比如包里的 `/usr/bin/a` 就被放到了系统的 `/usr/bin/a`)。
     - **执行脚本**:在解压前后,按顺序执行 `control` 里的脚本(比如停止旧服务、创建用户)。
     - **登记造册**:将这次操作写入 `/var/lib/dpkg/status` 数据库。
- **本质总结**:它是**最底层的打包安装器**。它只负责"解压文件到根目录"和"写日志",**不会帮你解决依赖**,缺依赖就报错。

---

### 3. 二进制压缩包(tar.gz):纯粹的"文件摆放"
这是最简单粗暴的方式,没有任何黑魔法。

- **底层原理**:
  1. **文件集合**:压缩包里的文件已经是编译好的机器码(`bin`)、库文件(`lib`)和配置文件(`conf`)。
  2. **安装行为**:你执行 `tar -zxvf`,本质只是**把这一堆文件从压缩包里取出来,放到你指定的文件夹里**(比如 `/usr/local/jdk/`)。这个操作**完全不触碰系统数据库**(`/var/lib/dpkg`),也不执行任何系统脚本。
  3. **系统如何找到它**:系统不会主动去 `/usr/local/jdk/bin` 里找程序。你必须在 `~/.bashrc` 里设置 `PATH` 环境变量。当你在终端敲 `java` 时,Shell 会去 `PATH` 列出的所有目录里挨个找,直到在你配置的目录里找到 `java` 命令。
- **本质总结**:它是一堆**散装文件**。系统的包管理器(APT/dpkg)**根本不知道它的存在**,全靠环境变量 `PATH` 让 Shell 能够定位到它。

---

### 4. 源代码编译安装:"现场制造"的过程
源码安装的本质不是"安装",而是**"编译"** + **"复制"**。

- **底层原理**:
  1. **预处理与配置(`./configure` 或 `cmake`)**:这一步是在你的机器上做"环境适配"。它会扫描你当前系统(比如找 GCC 编译器在哪、找 OpenCV 的头文件在哪),生成专属于你这台机器的 `Makefile` 文件。
  2. **编译(`make`)**:这是最核心的一步。GCC/G++ 编译器读取 `.c` / `.cpp` 源代码,根据 `Makefile` 的指引,在你的 CPU 上**实时地把人类代码翻译成二进制机器码**,生成 `.o` 目标文件,最后链接成可执行文件。这个过程是纯 CPU 计算,不涉及任何系统写入。
  3. **安装(`sudo make install`)**:这一步只是把上一步生成的**二进制文件复制**到系统目录(如 `/usr/local/bin`)。有时候也会把库文件复制到 `/usr/local/lib`。
- **本质总结**:它的产物(二进制文件)和**方法三**一模一样,但**唯一的区别**是:方法三的二进制是别人提前编译好的,而方法四的二进制是你用自己电脑 CPU 现场"焊接"出来的,因此兼容性往往更好,且可以自由开关编译选项。

---

### 💎 一张表彻底看透本质

| 对比维度 | **方法一:APT** | **方法二:dpkg (.deb)** | **方法三:二进制包 (.tar.gz)** | **方法四:源码编译** |
| :--- | :--- | :--- | :--- | :--- |
| **文件来源** | 远程官方仓库 | 本地手动下载 | 本地手动下载 | 远程源码仓库 (Git) |
| **核心动作** | **下载 + 解压 + 依赖解析** | **解压到根目录** | **解压到自定义目录** | **编译 + 复制文件** |
| **是否触及系统数据库** | **是**(写入 `/var/lib/dpkg`) | **是**(写入 `/var/lib/dpkg`) | **否**(完全不知道) | **否**(除非手动注册) |
| **系统如何识别** | 数据库 + `PATH` | 数据库 + `PATH` | **仅靠 `PATH` 环境变量** | **仅靠 `PATH` 或绝对路径** |
| **卸载原理** | 删除文件 + 擦除数据库记录 | 删除文件 + 擦除数据库记录 | **直接 `rm -rf` 文件夹** | `make uninstall` 或手动删 |

**终极认知**:
在 Linux 眼里,**"安装"只有两个本质动作**:

1.  **把文件放到系统目录下**(让 `PATH` 能找到)。
2.  **在数据库里登记一下**(方便 `apt remove` 或 `dpkg -l` 查询)。

**方法一、二**做了全套(放文件 + 写数据库);**方法三、四**只做了"放文件"(没写数据库)。这就是为什么方法三、四卸载得手动删,而 APT 一个命令就搞定了。理解了这一点,你就能随意拿捏 Ubuntu 的软件生态了。 👍
相关推荐
天疆说1 小时前
在 Ubuntu 的 VSCode 中配置 MATLAB
vscode·ubuntu·matlab
云飞云共享云桌面9 小时前
传统工作站 vs 云飞云共享云桌面:制造业设计云桌面选型深度对比
运维·服务器·前端·网络·3d·架构·制造
暮云星影12 小时前
全志linux开发屏幕适配(一)屏幕参数设置说明
linux·arm开发
Maynor99612 小时前
我用 Codex 给自己的网站上线了一个智能体客服:从 Dify 到服务器部署,全程实战复盘
运维·服务器
kiros_wang13 小时前
鸿蒙 ArkUI:V1 与 V2 装饰器全面对比与迁移指南
ubuntu·华为·harmonyos
java_cj13 小时前
深入kubectl create源码:从YAML到Pod的完整链路拆解
运维·云原生·容器·kubernetes
swordbob14 小时前
NIO 的 Channel 里有多个 BIO 吗?
linux·网络·nio
深圳恒讯14 小时前
越南服务器BGP多线和单线有什么区别?
运维·服务器
Fcy64814 小时前
Linux下 信号的保存与捕捉
linux·中断·信号的捕捉·信号的保存