activate:uv环境管理

环境约定

  • 解释器本体:~/.local/share/uv/python # 激活环境时,UV用环境目录内的pyvenv.cfg和软链接技术重定向创建一个venv
  • 安装的包本体:~/.cache/uv # 在环境内安装包时,UV用硬链接技术,使多个环境指向磁盘上的同一份物理文件,不占额外空间
  • 环境home约定:/s500data/envs/<名称>

原始命令

uv --version 									# 查看 uv 版本
uv python list 									# 支持的Python版本:推荐的
uv python list --all-versions 					# 支持的Python版本:全部

uv venv --python 3.13 /s500data/envs/py313 		# 创建环境
source /s500data/envs/py313/bin/activate 		# 激活环境
deactivate 										# 退出环境

uv pip install --python /s500data/envs/py313/bin/python requests 			# 在指定虚拟环境中安装依赖包
uv pip install --python /s500data/envs/py313/bin/python -r requirements.txt # 根据 requirements.txt 批量安装依赖
uv pip list --python /s500data/envs/py313/bin/python 						# 查看指定虚拟环境已安装的包列表
uv pip freeze --python /s500data/envs/py313/bin/python 						# 导出指定虚拟环境的包依赖
uv pip sync --python /s500data/envs/py313/bin/python requirements.txt 		# 根据 requirements.txt 同步虚拟环境依赖
uv pip uninstall --python /s500data/envs/py313/bin/python requests 			# 卸载指定虚拟环境中的包

uv cache dir 									# 查看 uv 缓存目录
uv cache clean 									# 清理 uv 缓存
uv cache prune 									# 移除未使用的 uv 缓存

/etc/nixos/modules/system/service/uv.nix

  # 交互式 shell 里启用 activate 函数(uv 虚拟环境管理);import 本模块即生效
  programs.bash.interactiveShellInit = ''
    [ -r ${./uv_activate.sh} ] && source ${./uv_activate.sh}
  '';

/etc/nixos/modules/system/service/uv_activate.sh

# /etc/nixos/scripts/activate.sh
# 用法:在 ~/.bashrc 里 source 本文件

# 定义统一的 uv 环境根目录(幂等,可重复 source)
export UV_ENV_HOME="${UV_ENV_HOME:-/s500data/envs}"

# 智能管理环境:
# 1. activate            -> 退出当前虚拟环境 (deactivate)
# 2. activate py313      -> 激活已存在的 py313 环境(不存在则报错)
# 3. activate py313 3.13 -> 自动以 Python 3.13 创建 py313 并直接激活
activate() {
    local name="$1"
    local py_ver="$2"

    if [ -z "$name" ]; then
        if command -v deactivate &> /dev/null; then
            deactivate
        else
            echo "Error: No active virtual environment found."
            return 1
        fi
        return 0
    fi

    local target_path="$UV_ENV_HOME/$name"

    if [ -n "$py_ver" ]; then
        echo "Creating environment '$name' with Python $py_ver..."
        uv venv --python "$py_ver" "$target_path"
        if [ $? -ne 0 ]; then
            echo "Error: Failed to create environment '$name'."
            return 1
        fi
    fi

    if [ -f "$target_path/bin/activate" ]; then
        source "$target_path/bin/activate"
        echo "Activated environment: $name"
    else
        echo "Error: Environment '$name' not found in $UV_ENV_HOME. Use 'activate <name> <python_version>' to create it."
        return 1
    fi
}

# 用 uv pip 无缝覆盖替代系统的 pip 命令
pip() {
    if [ -n "$VIRTUAL_ENV" ]; then
        uv pip --python "$VIRTUAL_ENV/bin/python" "$@"
    else
        command pip "$@"
    fi
}

注意事项

  • uv 装不了 Python 3.6.8:它的托管清单最老只到 cpython-3.8.9(实测 uv python list --all-versions),nixpkgs 26.05 也已裁掉 python36/37 —— 3.6.8 需要走 conda 或 docker
  • 环境名与所装 python 版本无关 —— /s500data/envs/guodu368 这个名字的 venv 用 3.13 也能建,但 3.6.8 的解释器 uv 给不了
  • 同一 python 小版本的环境之间,site-packages 通过 ~/.cache/uv 硬链接共享(实测 inode 相同),跨大版本不共享(wheel 是不同构建)
  • --python <venv绝对路径>/bin/python 比 activate 更适合脚本,两写法已各测