- 开发工具
- CLI
- 包管理器
- 任务调度
【免费下载链接】pixi
Powerful system-level package manager for Linux, macOS and Windows written in Rust – building on top of the Conda ecosystem.
pixi global是 pixi 提供的全局工具管理能力:把 Conda 生态的包安装到系统级位置、暴露可执行文件到PATH,让你在任意目录都能直接运行命令行工具。本文围绕 docs/global_tools/introduction.md 展开,从基本安装、依赖组合、暴露控制、源码安装、Shell 补全到全局 Manifest 与底层 trampoline 机制逐一深入,并佐以 pixi_cli 的 install 实现 与 pixi_global 库 的源码证据。读完本文,你将能熟练使用pixi global install的各类参数,理解其"环境隔离 + 精准暴露"的设计,并掌握全局清单文件的编辑、同步与迁移。
什么是 pixi global
pixi global的核心思路是:将工具安装在一个全局位置,并把可执行文件暴露到系统PATH中,使工具从任何目录都可以直接运行。与项目级pixi环境不同,全局安装的环境不绑定某个项目目录,而是存放在由PIXI_HOME指定的目录(默认是~/.pixi,见 环境变量参考)。
从源码看,这个设计非常清晰:
- 全局可执行目录
BinDir默认为$PIXI_HOME/bin(见 crates/pixi_global/src/common.rs 中BinDir::from_env); - 全局环境根目录
EnvRoot默认为$PIXI_HOME/envs,每个环境对应一个独立子目录; - 部分带图形界面的包还会自动添加开始菜单快捷方式(
shortcuts机制)。
默认行为:每个包一个独立环境
运行下面的命令即可把rattler-build安装到系统:
pixi global install rattler-buildpixi global的默认设计是把每个包隔离在自己的环境中,只暴露必要的人口点(entry points)。这意味着删除一个包不会误伤看起来无关的其他包——这一点与pipx的行为非常相似。从 install.rs 的实现可以看出,未指定--environment时,每个 spec 会被映射为独立的EnvironmentName,各自求解、安装、暴露:
None => specs .into_iter() .map(|spec| { ( EnvironmentName::from_str(spec.name().as_normalized()) .expect("valid environment name"), vec![spec], ) }) .collect(),安装时的完整流程
pixi global install的底层执行链(setup_environment,见 install.rs)大致为:
- 发现或创建全局项目(
Project::discover_or_create),加载全局 Manifest; - 为环境确定 channels(默认
conda-forge,可由--channel覆盖); - 在 Manifest 中新增环境、写入依赖与暴露映射(
add_environment/add_dependency/add_exposed_mapping); - 检查环境是否已同步;若未同步则求解并安装环境(
install_environment_with_options); - 同步暴露名称(
sync_exposed_names)、同步快捷方式(sync_shortcuts,前提是--no-shortcuts未指定); - 暴露可执行文件(
expose_executables_from_environment); - 同步 Shell 补全(
sync_completions); - 保存 Manifest。
基本用法与核心参数
pixi global install的完整用法(见 CLI 参考):
pixi global install [OPTIONS] [PACKAGE]...常用参数一览(与 install.rs 中的Args结构一一对应):
| 参数 | 说明 |
|---|---|
PACKAGE... | 依赖名或 Conda MatchSpec,可指定多次 |
-c, --channel <CHANNEL> | 指定 channel(名字或 URL),可多次;默认conda-forge |
-p, --platform <PLATFORM> | 为目标平台安装(如osx-64) |
-e, --environment <ENV> | 把所有包安装进同一个环境 |
--expose <EXPOSED=EXECUTABLE> | 指定暴露映射,语法exposed_name=executable_name |
--with <SPEC> | 额外加入环境的依赖,其可执行文件不会被暴露 |
--force-reinstall | 强制重装环境 |
--no-shortcuts | 不为已安装包创建快捷方式 |
--path <PATH> | 从本地路径安装源码包 |
--git <URL> | 从 git 仓库安装源码包 |
--build-backend <BACKEND> | 源码无包清单时指定构建后端(可带版本约束) |
--package <KEY=VALUE> | 以内联包定义方式补充package下的字段 |
--branch / --tag / --rev / --subdirectory | git 来源的细化选择 |
注意:当一次安装多个包(多环境)时,
--expose与--with会报错,因为这两个选项只对单一环境有意义(install.rs 中显式miette::bail!)。
在同一个环境中组合依赖:--with
ipython单独用很方便,但配合numpy、matplotlib才真正强大。此时你希望这些依赖出现在同一个环境中:
pixi global install ipython --with numpy --with matplotlib--with添加的包不会暴露它们的可执行文件——numpy确实提供了可执行程序,但由于是通过--with加入的,其可执行文件不会出现在PATH上。这正符合"只暴露主工具"的预期。验证方式:
ipython -c 'import numpy; import matplotlib'从源码看,--with对应的可执行文件被显式排除在自动暴露之外:sync_exposed_names中,当存在--with包名时使用ExposedType::Ignore(with_package_names),即在自动暴露全部可执行文件时忽略这些包(见 install.rs)。这与 manifest.md 中ipython环境条目的依赖结构一致:dependencies = { ipython = "*", numpy = "*", matplotlib = "*" }。
自定义暴露名称:--expose
同一包的不同版本不能同名暴露在PATH上,因此需要不同的对外名称:
pixi global install --expose py3=python "python=3.12"--expose py3=python表示把python可执行文件暴露为py3。一旦指定了--expose,该环境就不再自动暴露其他可执行文件(例如python包附带的pip、python3等不会自动出现)。之后即可用新名字运行:
py3 -c "print('Hello World')"Manifest 中会记录:
[envs.python] channels = ["conda-forge"] dependencies = { python = "3.12.*" } exposed = { py3 = "python" }嵌套目录中的可执行文件
某些可执行文件位于包的嵌套目录里(例如dotnet安装在dotnet子目录中)。此时需要写相对路径:
pixi global install dotnet --expose dotnet=dotnet\dotnet对应 Manifest 条目为exposed = { dotnet = 'dotnet\dotnet' }。Windows 上暴露名会自动追加.exe后缀(见 common.rs 的executable_trampoline_path,且专门避免用set_extension破坏python3.9.1这类含点的名字)。
从源码安装全局工具
pixi global也支持安装从源码构建的 pixi 包(即包含 pixi 包清单的项目,详见 源码依赖一节)。
准备包清单
假设有一个 C++ 包希望全局安装,它需要一份包清单:
[package] name = "cpp_math" version = "0.1.0" [package.build] backend = { name = "pixi-build-cmake" }本地路径与 git 仓库
源码在本地:
pixi global install --path /path/to/cpp_math源码在 git 仓库:
pixi global install --git https://github.com/ORG_NAME/cpp_math.git多输出(multi-output)包
如果源码包含多个输出,需要指定要安装哪一个。例如下面的 recipe 同时产出foobar与bizbar两个包:
recipe: name: multi-output version: "0.1.0" outputs: - package: name: foobar build: script: - if: win then: - if not exist %PREFIX%\bin mkdir %PREFIX%\bin - echo @echo off > %PREFIX%\bin\foobar.bat - echo echo Hello from foobar >> %PREFIX%\bin\foobar.bat else: - mkdir -p $PREFIX/bin - echo "#!/usr/bin/env bash" > $PREFIX/bin/foobar - echo "echo Hello from foobar" >> $PREFIX/bin/foobar - chmod +x $PREFIX/bin/foobar - package: name: bizbar build: script: - if: win then: - if not exist %PREFIX%\bin mkdir %PREFIX%\bin - echo @echo off > %PREFIX%\bin\bizbar.bat - echo echo Hello from bizbar >> %PREFIX%\bin\bizbar.bat else: - mkdir -p $PREFIX/bin - echo "#!/usr/bin/env bash" > $PREFIX/bin/bizbar - echo "echo Hello from bizbar" >> $PREFIX/bin/bizbar - chmod +x $PREFIX/bin/bizbar此时必须显式指明安装哪个输出:
pixi global install --path /path/to/package foobar无包清单的仓库:--build-backend
若源码是普通的 Rust、Python 或 C++ 仓库,没有包清单,可以在命令行直接指定构建后端:
pixi global install --git https://github.com/BurntSushi/xsv.git --build-backend pixi-build-rust这条命令会在全局 Manifest 中记录一个内联包定义(inline package definition),即 manifest.md 的 source dependencies 一节 描述的形式:
[envs.xsv] channels = ["conda-forge"] [envs.xsv.dependencies] xsv = { git = "https://github.com/BurntSushi/xsv.git", package.build.backend.name = "pixi-build-rust" }--build-backend支持版本约束,例如--build-backend "pixi-build-rust>=0.3,<0.4";也可以用--package DOTTED_KEY=TOML_VALUE直接设置package下的任意字段,值必须是合法 TOML(字符串需要带引号):
pixi global install --git https://github.com/some/tool \ --build-backend pixi-build-python \ --package 'host-dependencies.hatchling="*"'这些 CLI 旗标本质上是手写内联包定义(用pixi global edit可手动编辑)的快捷方式。注意两个重要限制:
- 源码依赖在本地机器上构建,因此包含源码依赖的环境只能面向当前平台,为其设置其他平台会报错;
pixi global sync只在spec 变化(如 git revision 或package表被编辑)时重建源码依赖;要获取未固定 git 依赖的新提交或本地路径的新内容,需运行pixi global update(见 sync 参考、update 参考)。
一次安装多个工具
不指定环境时,可以一次安装多个工具,各自独立成环境:
pixi global install pixi-pack rattler-build命令会在 Manifest 中生成两个互不干扰的环境,各自只暴露必要的最小二进制:
[envs.pixi-pack] channels = ["conda-forge"] dependencies= { pixi-pack = "*" } exposed = { pixi-pack = "pixi-pack" } [envs.rattler-build] channels = ["conda-forge"] dependencies = { rattler-build = "*" } exposed = { rattler-build = "rattler-build" }创建数据科学沙盒环境
想在一个环境里同时拥有 jupyter、ipython、numpy、pandas 与 matplotlib,用--environment指定环境名:
pixi global install --environment>[envs.data-science] channels = ["conda-forge"] dependencies = { jupyter = "*", ipython = "*" } exposed = { jupyter = "jupyter", ipython = "ipython" }注意:numpy、pandas、matplotlib只是环境依赖,不暴露二进制;只有显式列出的jupyter与ipython暴露。之后全局即可运行:
> ipython # Or > jupyter lab无需切换环境即可随时使用这些工具。
为不同平台安装包:--platform
--platform可用于为目标平台安装包,典型场景是在osx-arm64上安装osx-64的包:
pixi global install --platform osx-64 python生成的 Manifest 条目:
[envs.python] channels = ["conda-forge"] platforms = ["osx-64"] dependencies = { python = "*" } # ...从 manifest.md 可知,每个环境只针对单一平台求解(默认当前平台)。部分包受虚拟包(如__cuda)约束,这些约束在每次求解时从本机探测,install、update、sync都会遵守;可用CONDA_OVERRIDE_*环境变量覆盖探测结果:
CONDA_OVERRIDE_CUDA=12.0 pixi global install <SomeCudaTool>再次强调:含源码依赖的环境只能面向当前平台。
Shell 补全:自动安装
在终端里输入git -后按<TAB>,shell 能列出git的全部旗标——前提是补全脚本已安装。通过pixi global install安装的工具,若包内含补全脚本,会被自动安装。目前仅支持 Linux 与 macOS。
先安装工具:
pixi global install git补全脚本位于$PIXI_HOME/completions下(默认~/.pixi/completions)。从 completions.rs 可以看到目录结构:bash/、zsh/、fish/三个子目录,补全脚本以符号链接形式从环境前缀指向全局补全目录。
在 shell 启动脚本中加载补全:
# bash, default on most Linux distributions for file in ~/.pixi/completions/bash/*; do [ -e "$file" ] && source "$file" done# zsh, default on macOS fpath+=(~/.pixi/completions/zsh) autoload -Uz compinit compinit# fish for file in ~/.pixi/completions/fish/* source $file end两点提醒:
- 补全仅在可执行文件以原名暴露时生效,例如
exposed = { git = "git" }(completions.rs 中completions_sync_status只对exposed_name == executable_name的映射安装补全); - 如果某个 CLI 工具的补全缺失,可以像 Conda Forge feedstock 的做法一样,在打包 recipe 中补上补全脚本。
全局 Manifest 详解
所有全局环境、依赖与暴露映射都记录在全局 Manifest(pixi-global.toml)中。它可以被编辑、同步、纳入版本控制并与他人共享。运行 manifest.md 中的命令后会得到形如:
version = 1 [envs.rattler-build] channels = ["conda-forge"] dependencies = { rattler-build = "*" } exposed = { rattler-build = "rattler-build" } [envs.ipython] channels = ["conda-forge"] dependencies = { ipython = "*", numpy = "*", matplotlib = "*" } exposed = { ipython = "ipython", ipython3 = "ipython3" } [envs.python] channels = ["conda-forge"] dependencies = { python = "3.12.*" } exposed = { py3 = "python" }Manifest 位置与优先级
用pixi info可查看当前使用的 Manifest 路径。不同系统的查找优先级如下:
=== "Linux"
| **优先级** | **位置** | **说明** | |-----------|---------|---------| | 4 | `$PIXI_HOME/manifests/pixi-global.toml` | `PIXI_HOME` 下的全局 Manifest | | 3 | `$HOME/.pixi/manifests/pixi-global.toml` | 用户主目录 | | 2 | `$XDG_CONFIG_HOME/pixi/manifests/pixi-global.toml` | XDG 兼容配置目录 | | 1 | `$HOME/.config/pixi/manifests/pixi-global.toml` | 配置目录 |=== "macOS"
| **优先级** | **位置** | **说明** | |-----------|---------|---------| | 3 | `$PIXI_HOME/manifests/pixi-global.toml` | `PIXI_HOME` 下的全局 Manifest | | 2 | `$HOME/.pixi/manifests/pixi-global.toml` | 用户主目录 | | 1 | `$HOME/Library/Application Support/pixi/manifests/pixi-global.toml` | 配置目录 |=== "Windows"
| **优先级** | **位置** | **说明** | |-----------|---------|---------| | 3 | `$PIXI_HOME\manifests/pixi-global.toml` | `PIXI_HOME` 下的全局 Manifest | | 2 | `%USERPROFILE%\.pixi\manifests\pixi-global.toml` | 用户主目录 | | 1 | `%APPDATA%\pixi\manifests\pixi-global.toml` | 配置目录 |若多个位置同时存在,将使用优先级最高的那个。
channels:频道优先级
channels描述下载包所用的 Conda channel,按顺序优先级递减:第一个优先级最高,找不到包时依次尝试下一个。例如:
pixi global install --channel conda-forge --channel bioconda snakemake会生成:
[envs.snakemake] channels = ["conda-forge", "bioconda"] dependencies = { snakemake = "*" } exposed = { snakemake = "snakemake" }channel 的更多细节见 channel 逻辑文档。
dependencies:依赖管理
依赖是安装进环境的 Conda 包,通常只需指定主工具,但也可添加更多包。例如:
pixi global install "python<3.12"生成:
[envs.vim] channels = ["conda-forge"] dependencies = { python = "<3.12" } # ...(示例环境名沿用vim只是文档中的演示,实际以包名为准。)指定--environment可一次添加多个依赖:
pixi global install --environment my-env git vim python生成:
[envs.my-env] channels = ["conda-forge"] dependencies = { git = "*", vim = "*", python = "*" } # ...后续可用pixi global add向已有环境追加依赖(不会自动暴露新包的可执行文件):
pixi global add --environment my-env package-a package-b用pixi global remove移除:
pixi global remove --environment my-env package-a package-bexclude-newer:规避新发布包
[global]表中的exclude-newer键可为清单中所有环境的求解设置一个时间截止点,排除之后上传的包,降低安装到可能存在问题的新发布包的风险。取值与工作区清单一致:RFC 3339 时间戳、YYYY-MM-DD日期(按次日 UTC 零点解释,如2026-03-30表示2026-03-31T00:00:00Z)或相对当前求解时间的时长。channel 可自带exclude-newer覆盖全局截止点,[exclude-newer]表可针对单个包覆盖:
version = 1 [global] exclude-newer = "7d" [exclude-newer] my-tool = "0d" [envs.tools] channels = [ { channel = "https://my.internal/channel", exclude-newer = "0d" }, "conda-forge", ] dependencies = { my-tool = "*" } exposed = { my-tool = "my-tool" }优先级为:包级覆盖 > channel 级覆盖 >[global]截止点。两个表可独立使用:没有[global]截止点时,只有被覆盖的包/channel 会被排除。全局环境没有 PyPI 依赖,因此没有与工作区[pypi-exclude-newer]对应的机制。环境内若存在比截止点更新的包会被视为不同步,收紧截止点后下一次pixi global sync会重新求解。
exposed:自动暴露与重命名
--expose bird=bat bat会把bat可执行文件暴露为bird:
[envs.bat] channels = ["https://prefix.dev/conda-forge"] dependencies = { bat = "*" } exposed = { bird = "bat" }还有一条自动行为:当包名与环境名一致时,该包会以同名自动暴露——即使二进制实际由包的依赖提供。例如:
pixi global install ansible生成:
[envs.ansible] channels = ["conda-forge"] dependencies = { ansible = "*" } exposed = { ansible = "ansible" }这里的ansible二进制其实由ansible的依赖ansible-core提供,但仍按原名暴露。
shortcuts:图形应用的快捷方式
对 GUI 应用,包若自带 menuinst 快捷方式定义,pixi global install会自动处理,无需额外操作:
[envs.mss] channels = ["https://prefix.dev/conda-forge"] dependencies = { mss = "*" } exposed = { ... } shortcuts = ["mss"]shortcuts存在时,pixi 会为mss安装开始菜单快捷方式。从 common.rs 的contains_menuinst_document与shortcuts_sync_status可以看到:pixi 通过检查包记录中Menu/目录下的 menuinst JSON 文档来判定包是否带快捷方式,并与 Manifest 请求做差集以决定安装/卸载。想打包带快捷方式的应用,可在 recipe 中遵循 menuinst 规范提供对应 JSON。
底层机制:trampolines 与目录布局
trampolines:免激活脚本的性能优化
为了提升效率,pixi 使用trampolines——一种小型专用二进制文件,负责在执行主程序前完成配置与环境设置(详见 trampolines.md)。采用 trampoline 方案可以跳过激活脚本的执行,避免其显著的性能开销。
执行一个全局安装的可执行文件时,trampoline 依次完成:
- 读取以可执行文件命名的 JSON 配置文件(如
python.json),其中包含环境如何设置的关键信息;配置文件存放在$PIXI_HOME/bin/trampoline_configuration; - 加载配置并设置好环境后,以正确的环境设置执行原始二进制;
- 安装新二进制时,trampoline 被放入
$PIXI_HOME/bin,并通过硬链接指向$PIXI_HOME/bin/trampoline_configuration/trampoline_bin,从而节省存储空间、避免同一 trampoline 重复存放。
trampoline 还会保证PATH始终包含你本地PATH的最新变化,同时避免缓存安装期间的临时PATH改动。如果你想控制 pixi 所考虑的基准PATH,可在 shell 启动脚本中设置:
export PIXI_BASE_PATH=$PATH对应目录布局(默认~/.pixi):
| 目录 | 用途 |
|---|---|
~/.pixi/bin | 暴露到PATH的 trampoline/脚本 |
~/.pixi/envs/<env> | 每个全局环境的前缀目录 |
~/.pixi/manifests/pixi-global.toml | 全局 Manifest |
~/.pixi/completions/{bash,zsh,fish} | Shell 补全脚本 |
~/.pixi/bin/trampoline_configuration | trampoline 的 JSON 配置与共享二进制 |
控制CONDA_PREFIX:为打包作者准备的开关
pixi 在运行全局暴露的可执行文件之前会激活目标环境,这通常会设置CONDA_PREFIX指向该环境的路径。有些工具会检查CONDA_PREFIX并期望它指向标准 Conda 安装,当工具运行在 pixi 管理的前缀下时可能产生令人困惑的行为。
打包作者可以让包退出导出CONDA_PREFIX:在环境内为每个可执行文件放置一个标记文件etc/pixi/<executable>/global-ignore-conda-prefix(例如可执行文件名为borg时放在etc/pixi/borg/global-ignore-conda-prefix)。当该标记文件存在时,pixi 会从环境变量中移除CONDA_PREFIX,让工具表现得像没有激活任何 Conda 环境。
构建带borg可执行文件的包的 recipe 片段:
build: script: - mkdir -p $PREFIX/etc/pixi/borg - touch $PREFIX/etc/pixi/borg/global-ignore-conda-prefixpixi global install安装这类包后,暴露的可执行文件不再看到CONDA_PREFIX,可以回落到默认行为。