强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

GNU Guix 函数式包管理教程 / 第三章 基本操作

第三章:基本操作

3.1 操作总览

Guix 的命令行工具遵循一致的子命令模式:

guix <子命令> [选项] [参数]

常用子命令速查表

子命令功能示例
search搜索包guix search vim
install安装包guix install vim
remove删除包guix remove vim
upgrade升级包guix upgrade
show查看包详情guix show vim
pull更新通道guix pull
gc垃圾回收guix gc
shell创建临时环境guix shell python
build构建包guix build vim
package包管理(旧语法)guix package -i vim

3.2 搜索包

3.2.1 基本搜索

# 按名称搜索
guix search video player

# 搜索特定名称
guix search ^vim

# 输出为 Scheme 格式
guix search vim --output-format=recutils

3.2.2 查看包详情

# 查看包的完整信息
guix show vim

# 输出示例:
# name: vim
# version: 9.0.1
# outputs: out
# source: ...
# inputs: ncurses, gpm, ...
# home-page: https://www.vim.org/
# synopsis: Text editor
# description: Vim is a highly configurable text editor...
# license: vim-license

3.2.3 列出已安装的包

# 查看当前 profile 中的包
guix package --list-installed

# 输出示例:
# vim    9.0.1    out    /gnu/store/...
# git    2.40.0   out    /gnu/store/...

3.2.4 搜索的实际应用场景

场景:查找某个库的开发包

# 不确定开发包的名称?搜索试试
guix search openssl | grep -i dev
guix show openssl
# 查看 outputs 字段:通常包含 out 和 dev

场景:查找某个命令属于哪个包

# 使用 guix search 或 guix locate
guix search "the command" provides
# 或者使用反向查找
guix package --search-paths=prefix

3.3 安装包

3.3.1 基本安装

# 安装单个包
guix install vim

# 安装多个包
guix install git htop tree curl

# 安装特定输出(如开发头文件)
guix install openssl:dev

3.3.2 安装到特定 Profile

# 默认 profile(~/.guix-profile)
guix install vim

# 指定 profile
guix install -p ~/my-profiles/development vim python

# 为特定项目创建独立 profile
mkdir -p ~/my-profiles/project-a
guix install -p ~/my-profiles/project-a node python

3.3.3 使用 Manifest 安装

Manifest 是声明式包列表,适合管理一组相关包:

;; ~/dev-tools.scm
(specifications->manifest
  '("git"
    "vim"
    "python"
    "python-pip"
    "docker-cli"
    "openssh"))
# 使用 manifest 安装
guix package --manifest=~/dev-tools.scm

💡 提示:Manifest 方式优于逐个安装,因为它是声明式的,可以在多台机器间共享,也方便版本控制。


3.4 升级包

3.4.1 升级流程

Guix 的升级分为两步:

# 步骤一:更新通道(拉取最新的包定义)
guix pull

# 步骤二:升级已安装的包
guix upgrade

3.4.2 升级特定包

# 只升级特定包
guix upgrade vim git

# 升级到特定版本(通过通道指定)
# 通常需要修改通道配置或使用 time-machine

3.4.3 使用 time-machine 锁定版本

# 使用特定版本的 Guix 运行命令
guix time-machine --channels=channels.scm -- install vim

# channels.scm 中可以锁定到特定 commit

⚠️ 注意guix pull 会下载整个通道的包定义。首次拉取可能需要较长时间,后续更新通常是增量的。


3.5 删除包

# 删除单个包
guix remove vim

# 删除多个包
guix remove vim git htop

# 删除不会立即释放空间——旧版本仍在 store 中
# 需要配合垃圾回收(GC)才能释放空间

理解删除与卸载

安装前:  profile → store/abc...-vim-9.0
安装后:  profile → store/def...-vim-9.1  (同时 abc 版本仍在 store 中)
删除后:  profile 中无 vim 引用,但 store/abc... 和 store/def... 都还在
GC 后:   不被任何 profile 引用的 store 对象被清理

3.6 回滚(Rollback)

回滚是 Guix 最强大的特性之一——任何操作都可以撤销。

3.6.1 Profile 的 Generation 机制

每次 guix installguix removeguix upgrade 操作都会创建一个新的 generation(代):

# 查看所有 generation
guix package --list-generations

# 输出示例:
# Generation 1  May 01 2026 10:00:00
#   vim   9.0.1  out
#   git   2.39.0 out
#
# Generation 2  May 05 2026 14:30:00
#   vim   9.0.2  out  (升级)
#   git   2.40.0 out  (升级)
#   htop  3.2.1  out  (新增)
#
# Generation 3  May 10 2026 09:00:00  (current)
#   vim   9.0.2  out
#   htop  3.2.1  out
#   git 已删除

3.6.2 执行回滚

# 回滚到上一个 generation
guix package --roll-back

# 切换到特定 generation
guix package --switch-generation=2

# 简写形式
guix package -S 2

3.6.3 删除旧 Generation

# 删除特定 generation
guix package --delete-generations=1

# 删除 30 天前的 generation
guix package --delete-generations=30d

# 删除除当前外的所有 generation
guix package --delete-generations

3.6.4 回滚的实际场景

场景:升级导致软件不可用

# 发现 vim 9.0.2 有 bug
guix package --roll-back

# 或者精确回到旧版本
guix package --switch-generation=1

# 确认恢复
guix package --list-installed

💡 提示:Guix System 的回滚同样强大。guix system roll-back 可以将整个系统回退到上一次 reconfigure 的状态。


3.7 垃圾回收(Garbage Collection)

3.7.1 为什么需要 GC?

旧版本的包、已删除包的依赖、构建过程中的临时文件都会累积在 /gnu/store 中,占用磁盘空间。垃圾回收机制清理这些不再被引用的对象。

3.7.2 基本 GC 操作

# 查看 store 占用的空间
guix gc --list-dead       # 列出可回收的对象
guix gc --list-live       # 列出活跃的对象

# 执行垃圾回收
guix gc --collect-garbage
guix gc -C 5G            # 保留至少 5GB 空间

# 删除特定 store 路径
guix gc --delete /gnu/store/abc...-vim-9.0

3.7.3 GC 策略表

命令说明
guix gc -C 10G保留至少 10GB 空间
guix gc -D 30d删除 30 天前未使用的对象
guix gc --delete-generations先删除旧 generation 再 GC
guix gc -F 5G释放至少 5GB 空间

3.7.4 防止意外回收

# 标记某个 store 路径为 "根"(root),防止被回收
guix gc --referrers /gnu/store/abc...-vim-9.0

# 添加间接引用
guix gc --derivers /gnu/store/abc...-vim-9.0

⚠️ 注意:垃圾回收会永久删除不被引用的对象。执行前请确认没有其他 profile 或服务依赖这些对象。


3.8 Profile 管理

3.8.1 Profile 概念

Profile 是一组包的集合,表现为一个目录(含 bin/lib/share/ 等子目录),由指向 /gnu/store 的符号链接组成。

~/.guix-profile/
├── bin/     → /gnu/store/abc.../bin/
├── lib/     → /gnu/store/def.../lib/
├── share/   → /gnu/store/ghi.../share/
└── etc/     → /gnu/store/jkl.../etc/

3.8.2 Profile 类型

Profile 类型路径用途
默认 Profile~/.guix-profile用户日常使用的包
系统 Profile/run/current-system/profileGuix System 系统级包
自定义 Profile任意路径项目隔离、功能分组

3.8.3 创建自定义 Profile

# 创建目录
mkdir -p ~/profiles/dev

# 安装到自定义 profile
guix install -p ~/profiles/dev python node rust

# 激活自定义 profile
export PATH="$HOME/profiles/dev/bin:$PATH"

# 或者创建一个激活脚本
cat > ~/activate-dev.sh << 'EOF'
export PATH="$HOME/profiles/dev/bin:$PATH"
export GUIX_PROFILE="$HOME/profiles/dev"
source "$HOME/profiles/dev/etc/profile"
EOF
source ~/activate-dev.sh

3.8.4 Manifest 驱动的 Profile

;; ~/manifests/python-dev.scm
(specifications->manifest
  '("python"
    "python-pip"
    "python-virtualenv"
    "python-numpy"
    "python-pandas"
    "python-matplotlib"
    "gcc-toolchain"
    "pkg-config"))
# 使用 manifest 构建 profile
guix package --manifest=~/manifests/python-dev.scm -p ~/profiles/python-dev

# 更新 profile(从最新的 manifest)
guix package --manifest=~/manifests/python-dev.scm -p ~/profiles/python-dev --upgrade

3.9 使用 guix shell 创建临时环境

guix shell 是创建临时开发环境的最佳工具:

3.9.1 基本用法

# 创建包含 Python 的临时环境
guix shell python python-numpy -- python

# 创建纯净环境(不继承系统包)
guix shell --pure python python-numpy -- python

# 创建容器化环境(更强的隔离)
guix shell --container python -- python

3.9.2 对比三种模式

模式隔离程度是否继承系统包网络访问
guix shell
guix shell --pure
guix shell --container可选

3.9.3 使用 Manifest 创建环境

;; ~/project-env.scm
(specifications->manifest
  '("python"
    "python-requests"
    "python-flask"
    "postgresql"))
# 从 manifest 创建环境
guix shell --manifest=~/project-env.scm

# 在项目目录中放置 manifest
cp ~/project-env.scm ./manifest.scm
guix shell  # 自动使用当前目录的 manifest.scm

3.9.4 将环境导出为 Docker 镜像

# 从 shell 环境导出 Docker 镜像
guix shell --container --network \
  --expose=$(pwd) \
  python python-flask \
  -- guix pack -f docker -o image.tar.gz \
    python python-flask

3.10 常用操作备忘表

操作命令
搜索包guix search <关键词>
查看包详情guix show <包名>
安装包guix install <包名>
删除包guix remove <包名>
列出已安装guix package --list-installed
升级全部guix pull && guix upgrade
回滚guix package --roll-back
查看历史guix package --list-generations
垃圾回收guix gc -C <空间>
创建临时环境guix shell <包名>
查看通道guix describe
更新通道guix pull

3.11 实战练习

练习一:搭建 Python 开发环境

# 1. 搜索 Python 包
guix search python | head -20

# 2. 查看 Python 包详情
guix show python

# 3. 创建开发环境
guix shell python python-numpy python-pandas -- python3 -c "
import numpy as np
import pandas as pd
print('NumPy:', np.__version__)
print('Pandas:', pd.__version__)
"

练习二:体验回滚

# 1. 安装一个包
guix install tree
tree --version

# 2. 删除它
guix remove tree

# 3. 确认已删除
which tree  # 应该找不到了

# 4. 回滚
guix package --roll-back

# 5. 确认恢复
which tree  # 又回来了
tree --version

3.12 总结

本章学习了 Guix 的日常操作:

  1. 搜索与查看——guix searchguix show
  2. 安装与删除——guix installguix remove
  3. 升级与回滚——guix upgrade--roll-back
  4. 垃圾回收——guix gc 释放磁盘空间
  5. Profile 管理——多 profile 隔离环境
  6. 临时环境——guix shell 快速创建开发环境

下一章我们将深入包定义的内部结构。


扩展阅读