在 Linux 上安装与使用 uv:Python 项目管理、依赖、虚拟环境与多版本解释器一站式指南

如果你用 Python 工作过一段时间,你可能为了让几个项目跑起来而同时摆弄过 pip、virtualenv、pip-tools、pipx 和 pyenv。这些工具各管一件事,把它们串起来既慢又脆弱。uv 是一个能替代它们全部的单文件二进制程序。它由 Rust 编写,由 Astral(ruff 背后的团队)发布,在常见工作流中通常比 pip 快十倍到一百倍。

本指南讲解如何在 Linux 上安装 uv、用它创建和管理 Python 项目、添加依赖、使用虚拟环境,以及安装特定的 Python 版本。

快速参考

CommandDescription
uv init my-project使用 pyproject.toml 创建新项目
uv add requests添加依赖并更新锁文件
uv add --dev pytest添加开发依赖
uv remove requests移除依赖
uv sync从锁文件安装依赖
uv lock更新锁文件
uv run script.py在项目环境中运行命令
uv venv创建虚拟环境
uv pip install requests兼容 pip 的安装接口
uv python install 3.12安装特定 Python 版本
uv python list列出已安装与可用的 Python 版本
uv python pin 3.13将项目固定到某 Python 版本
uv tool install ruff全局安装 CLI 工具
uvx ruff check .免安装临时运行工具
uv self update将 uv 更新到最新版本
uv cache clean清理 uv 缓存

安装 uv

在 Linux 上,推荐的安装方式是 Astral 提供的独立脚本。它会下载一个预编译二进制文件,放到 ~/.local/bin,且无需预先安装 Python:

curl -LsSf https://astral.sh/uv/install.sh 
|
 sh

如果未安装 curl,wget 也能完成同样的任务:

wget -qO- https://astral.sh/uv/install.sh 
|
 sh

脚本会打印二进制文件的位置,以及它是否更新了你的 shell 配置文件。重新加载 shell 或运行 source ~/.bashrc 使新的 PATH 生效,然后验证安装:

uv --version
uv 0.12.12

若想固定到特定版本,而不是每次都取最新版,可以把版本号写进 URL。这在 CI runner 和共享构建机上很重要,因为一次未声明的升级可能改变锁文件的解析结果:

curl -LsSf https://astral.sh/uv/0.12.12/install.sh 
|
 sh

安装程序默认写入 ~/.local/bin,并可能修改你的 shell 配置文件。设置 UV_INSTALL_DIR 可把二进制放到其他位置,设置 UV_NO_MODIFY_PATH=1 则不改动你的 shell 文件。以下命令将 uv 安装到用户可写的 ~/bin 目录:

curl -LsSf https://astral.sh/uv/install.sh 
|
 env 
UV_INSTALL_DIR
=
"
$HOME
/bin"
 
UV_NO_MODIFY_PATH
=
1
 sh

由于该命令禁用了自动 PATH 修改,如果 ~/bin 还不在 PATH 中,请自行将其加入 PATH。

如果你更倾向从包管理器安装,uv 也可以通过 pip、pipx 和 Homebrew 获取:

pip install uv
pipx install uv
brew install uv

在 Ubuntu、Debian 及其衍生版上,pip 可能因为 Python 环境被标记为 externally managed 而拒绝系统级安装。此时请使用 pipx install uv 或独立安装脚本。关于 pip 与 apt 的指南解释了现代发行版为何会封禁这条安装路径。

如果你已经拥有 Rust 工具链,可以从源码构建 uv,不过这比下载预编译二进制文件耗时得多:

cargo install --locked uv

Ubuntu 和 Debian 软件仓库中的 uv

一个常见问题是 uv 能否通过 apt 安装。Ubuntu 24.04、25.10 和 26.04 都不提供 Astral 的 uv CLI,Debian 12 和 Debian 13 同样没有。在这些发行版上,请改用独立安装脚本或 pipx。

Debian testing 和 unstable 含有一个名为 uv 的源码包,但目前只构建出 python3-uv-build 包。该包提供 Python 构建后端,并不安装 uv 命令。26.04 之后的 Ubuntu 开发系列有一个提供完整 CLI 的独立包,但它落后于上游版本。在你的发行版档案收录该 CLI 包之前,独立安装脚本仍是务实之选。

确实存在一些更紧跟上游的第三方 apt 仓库。它们既不由 Astral 也不由发行版维护,因此在把它们加入重要机器之前,请像对待任何其他外部仓库一样谨慎。

通过 Snap 安装 uv

在运行 snapd 的 Ubuntu 及其他发行版上,uv 可从 Snap Store 获取:

sudo snap install astral-uv --classic

需要 classic 限制级别,因为 uv 会写入你的项目目录和主目录缓存,而严格受限的 snap 无法访问这些位置。该 snap 名为 astral-uv,但它注册了 uv 和 uvx 别名,因此你之后输入的仍是常用命令。此包由社区贡献者而非 Astral 维护,不过它紧跟上游版本。

更新与卸载 uv

如果你用独立安装脚本安装了 uv,可用以下命令将其更新到最新版本:

uv self update

该命令仅适用于独立安装。当 uv 来自 pip、pipx、Homebrew、Cargo 或 Snap 时,请通过相同的工具升级,例如 pipx upgrade uv、brew upgrade uv 或 sudo snap refresh astral-uv。对包管理器安装的 uv 运行 uv self update 会报错,而不会在你包管理器背后替换二进制文件。

通过安装它们的同一个工具卸载包管理器安装的 uv。根据你选择的方式,使用 pip uninstall uv、pipx uninstall uv、brew uninstall uv、cargo uninstall uv 或 sudo snap remove astral-uv。

对于独立安装,先查看哪些受管的 Python 版本和工具将被移除:

uv python list --only-installed

uv tool list

确认不再需要它们后,在 uv 仍在你的 PATH 中时移除缓存、受管 Python 版本和已安装的工具:

uv cache clean

rm -r 
"
$(
uv python dir
)
"


rm -r 
"
$(
uv tool dir
)
"

接下来,从默认安装目录删除二进制文件:

rm ~/.local/bin/uv ~/.local/bin/uvx

如果你安装时设置了 UV_INSTALL_DIR,请从该目录移除二进制文件。

项目的虚拟环境不受影响,因为每个虚拟环境都位于各自项目目录下的 .venv 中。

启用 Shell 补全

uv 会生成自己的补全脚本。把对应你所用 shell 的那一行追加进去,然后打开一个新 shell 使其生效:

echo
 
'eval "$(uv generate-shell-completion bash)"'
 >> ~/.bashrc

对于 Zsh,同样的写法适用于 ~/.zshrc:

echo
 
'eval "$(uv generate-shell-completion zsh)"'
 >> ~/.zshrc

Fish 从其自有目录读取补全:

echo
 
'uv generate-shell-completion fish | source'
 > ~/.config/fish/completions/uv.fish

uvx 是一个独立的二进制文件,拥有独立的补全,它采用 flag 形式而非子命令形式:

echo
 
'eval "$(uvx --generate-shell-completion bash)"'
 >> ~/.bashrc

创建项目

uv init 会搭建一个新项目,并在其中初始化一个 Git 仓库:

uv init my-project

cd
 my-project
Initialized project `my-project`

uv 默认创建一个打包项目,代码位于 src 下而非项目根目录:

my-project
├── .git
├── .gitignore
├── .python-version
├── README.md
├── pyproject.toml
└── src
    └── my_project
        └── __init__.py

my-project 中的连字符在模块名中会变成下划线,因为连字符在 Python 标识符中非法。.python-version 文件记录了项目期望的解释器,生成的 .gitignore 已排除 .venv 以及常见的构建产物。

生成的 pyproject.toml 包含项目元数据、一个入口点以及构建后端:

[
project
]


name
 
=
 
"my-project"


version
 
=
 
"0.1.0"


description
 
=
 
"Add your description here"


readme
 
=
 
"README.md"


requires-python
 
=
 
">=3.12"


dependencies
 
=
 
[]




[
project
.
scripts
]


my-project
 
=
 
"my_project:main"




[
build-system
]


requires
 
=
 
[
"uv_build>=0.12.12,<0.13"
]


build-backend
 
=
 
"uv_build"

requires-python 的值来自 uv 在系统中找到的解释器,因此你的可能与此处不同。如果你更想要扁平布局(项目根目录放一个 main.py,不使用构建系统,适合小型工具和一次性脚本),传入 --no-package:

uv init --no-package my-script

无论哪种方式,uv 尚未创建虚拟环境。这会在你首次添加依赖或在项目中运行命令时发生。

添加与移除依赖

要添加包,使用 uv add:

uv add requests

首次运行时,uv 会在项目根目录创建 .venv 目录,解析依赖图,写入一个把每个包及其传递性依赖都锁定的 uv.lock 文件,并将全部内容安装到 venv 中。requests 这一行也会被添加到 pyproject.toml 的 dependencies 下。

仅用于开发的依赖通过 --dev 放入一个独立分组:

uv add --dev pytest ruff

它们被记录在 pyproject.toml 的 dev 依赖组中,并安装到同一个 venv,但当你的项目作为库发布或安装时会被排除。

用 uv remove 移除依赖:

uv remove requests

uv 会更新 pyproject.toml、更新 uv.lock,并卸载该包以及任何不再需要的依赖。

在项目环境中运行代码

你无需手动激活虚拟环境。uv run 会在项目 venv 内执行命令,并在需要时先同步依赖。由于 uv init 写入了 [project.scripts] 入口,项目可以直接按名称运行:

uv run my-project
Hello from my-project!

同一条命令也适用于针对这些依赖运行的其他任务,例如测试套件:

uv run pytest

若要运行文件而非脚本入口点,通过 python 传入它。用 --no-package 创建的项目就是这样启动的,因为它们的代码放在顶层 main.py:

uv run python main.py

如果你更喜欢经典工作流,可以自己激活 venv。项目和其入口点会被安装进 .venv,因此环境激活后同样可以用名称运行:

source
 .venv/bin/activate

my-project

两种方式都可行,但 uv run 的优势在于每次调用都会让环境与 uv.lock 保持同步。

同步与复现环境

当你克隆一个使用 uv 的项目时,运行 uv sync 以安装 uv.lock 中精确锁定的版本:

uv sync
Resolved 12 packages in 5ms
Installed 12 packages in 110ms

uv sync 使用 uv.lock 中为当前平台和 Python 版本记录的版本。锁文件可跨系统移植,但平台标记可能在 Linux、macOS 或 Windows 上选择不同的包。这是要在 CI、Docker 构建以及每次全新检出时运行的命令。

如果 pyproject.toml 发生变动但锁文件已过时,用以下命令刷新锁:

uv lock

使用 uv lock --upgrade 将每个依赖提升到 pyproject.toml 版本约束允许的最新版本;使用 uv lock --upgrade-package requests 只提升单个包。

直接管理虚拟环境

uv 也可作为 virtualenv 的更快替代品。要在当前目录创建一个独立的 venv:

uv venv
Using Python 3.12.8
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate

用 --python 指定 Python 版本:

uv venv --python 3.11

指定不同的路径:

uv venv /tmp/myenv

一旦 venv 存在,就可以用 uv pip 作为常规 pip 命令的快速替代品:

uv pip install requests

uv pip install -r requirements.txt

uv pip freeze

uv pip list

uv pip 接口刻意与 pip 兼容,这让现有项目无需重组成基于 pyproject.toml 的项目就能轻松采用 uv。

若要重温经典虚拟环境,请参阅 Python 虚拟环境指南。

安装与管理 Python 版本

uv 可以在不触碰系统 Python 的情况下下载并管理 Python 解释器。列出可用与已安装的版本:

uv python list

安装特定版本:

uv python install 3.12
uv python install 3.11 3.13

下载的解释器位于 ~/.local/share/uv/python/ 下,独立于系统包管理器,因此这里不会干扰 apt 或 dnf 安装的 Python。要把项目绑定到其中一个版本,使用 uv python pin,它会把版本写入 .python-version 文件并打印所做的改动:

uv python pin 3.13

你也可以在创建虚拟环境时传入 --python:

uv venv --python 3.13

uv python install 会把 python3.12 这类带版本的可执行文件放到 ~/.local/bin。如果该目录不在你的 PATH 中,uv 可以帮你添加:

uv python update-shell

不再需要的解释器同样可以轻松移除:

uv python uninstall 3.11

当 uv run 启动项目时,它会读取 .python-version 与 pyproject.toml 中的 requires-python 约束,然后自动选择或下载匹配的解释器。要确认 shell 当前使用的是哪个解释器,请参阅检查 Python 版本的指南。

安装 CLI 工具

uv 内置了一个类似 pipx 的工具管理器。它在隔离环境中安装基于 Python 的 CLI,以免污染你的系统 Python:

uv tool install ruff

ruff 二进制现在已在你的 PATH 中。列出、升级或移除工具:

uv tool list

uv tool upgrade ruff

uv tool uninstall ruff

若要免永久安装地运行一个工具,使用 uvx(即 uv tool run 的别名):

uvx ruff check .

uvx 会把工具下载到缓存环境、运行它,并在后续调用时复用该缓存。这是试用 CLI 而不让它常驻的最快方式。

运行单文件脚本

Python 脚本可以通过 PEP 723 注释块内联声明依赖。uv run 会读取该块,并在执行脚本前搭建一个临时环境:

# /// script


# requires-python = ">=3.12"


# dependencies = [


#     "requests",


# ]


# ///




import
 
requests




response
 
=
 
requests
.
get
(
"https://api.github.com"
)


print
(
response
.
status_code
)

用以下命令运行脚本:

uv run script.py

uv 会创建一个临时 venv,安装 requests,运行脚本,并把该环境缓存起来留待下次使用。这种模式适用于完整项目显得过重的小型工具和一次性自动化。

故障排查

uv: command not found(安装后找不到 uv 命令)——安装程序把二进制放在 ~/.local/bin,它可能不在你的 PATH 中。在 shell 配置文件中加入 export PATH="$HOME/.local/bin:$PATH",然后重新加载 shell。用 which uv 验证。

Installation fails with "error: externally-managed-environment"(安装报 externally-managed-environment 错误)——这条信息来自系统 pip 而非 uv。请改用 pipx install uv 或独立安装脚本。在现代 Ubuntu 和 Debian 发行版上,不建议把 Python 包安装到系统 Python 中。

uv sync 安装的版本与预期不符——请确认 uv.lock 已提交到仓库。没有锁文件时,uv sync 会回退到从 pyproject.toml 解析,可能选到更新的版本。提交 uv.lock 以在多台机器间保持环境可复现。

uv cannot find a suitable Python interpreter(uv 找不到合适的 Python 解释器)——运行 uv python install 3.12(或你的项目所需的版本)让 uv 下载匹配的解释器。pyproject.toml 中的 requires-python 字段告诉 uv 哪些版本可接受。

Permission denied when installing to the system(向系统安装时权限被拒绝)——uv 不需要 root。如果命令提示输入 sudo,说明目标路径不对。请使用项目虚拟环境,或用 uv tool install 安装 CLI,而不是写入系统目录。

常见问题(FAQ)

uv 与 pip 有何不同?pip 把包安装到已有的 Python 环境中。uv 是一个完整的项目管理器:它创建并管理虚拟环境、锁定依赖、安装 Python 解释器,并运行脚本和工具。uv pip 还为只想获得速度、不想采用整套工作流的团队提供了兼容 pip 的替代命令。

uv 会取代 Poetry 或 Hatch 吗?对大多数项目来说会。uv 读取 Poetry 和 Hatch 使用的标准 pyproject.toml 格式,管理锁文件并处理依赖分组。如果你依赖 Poetry 插件或 Hatch 构建钩子的特定功能,迁移前请先评估这些需求。

uv 与现有的 requirements.txt 工作流兼容吗?兼容。uv pip install -r requirements.txt 可作为 pip install -r 的更快替代品;uv pip compile 能从你未锁定的输入生成已锁定的 requirements 文件,类似 pip-tools 的 pip-compile。

我可以在 Docker 中使用 uv 吗?可以,而且很合适。先复制 pyproject.toml 和 uv.lock,运行 uv sync --locked --no-install-project 在独立层安装依赖,然后复制其余源码并运行 uv sync --locked。把 /root/.cache/uv 挂载为构建缓存,可让下载的 wheel 在多次构建间保留。优先使用 --locked 而非 --frozen,因为前者在 uv.lock 与 pyproject.toml 不一致时让构建失败,而不是悄悄安装过期的锁文件。

uv 把下载的解释器和包缓存存放在哪里?解释器位于 ~/.local/share/uv/python/,用 uv tool install 安装的工具位于 ~/.local/share/uv/tools/,包缓存位于 ~/.cache/uv/。三者都遵循 XDG 基础目录规范,因此 XDG_DATA_HOME 和 XDG_CACHE_HOME 会一并移动它们。若想单独移动其中一个而不影响其余,可设置 UV_PYTHON_INSTALL_DIR、UV_TOOL_DIR 或 UV_CACHE_DIR。

结论

uv 把以前需要 pip、virtualenv、pip-tools、pipx 和 pyenv 才能完成的工作整合进一个快速的二进制文件。速度是最显眼的特性,但真正的收益是为项目、工具、脚本和 Python 版本提供了一套统一、一致的工作流。

关于 Linux 上相关的 Python 工具,请参阅 Ubuntu 26.04 安装 Python 指南和 Python 虚拟环境指南。