Skip to content
shell
#!/bin/bash

# ==============================================================================
#  test-pip-source.sh
#
#  一个用于测试不同 pip (PyPI) 源速度和延迟的 Shell 脚本。
#  它会测试延迟、清理缓存、安装一个包来衡量速度,并最后提供一份总结报告。
# ==============================================================================

# --- 配置 ---

# 你想用来测试的包 (选择一个体积适中的包)
# requests 是个不错的选择,因为它有依赖项,更能模拟真实场景。
TEST_PACKAGE="requests"

# 要测试的 PyPI 镜像源列表 (可以随意添加或删除)
SOURCES=(
    "https://pypi.org/simple/" # 官方 PyPI
    "https://pypi.tuna.tsinghua.edu.cn/simple/" # 清华大学
    "https://mirrors.aliyun.com/pypi/simple/" # 阿里云
    "https://mirrors.ustc.edu.cn/pypi/simple/" # 中国科学技术大学
    "https://repo.huaweicloud.com/repository/pypi/simple/" # 华为云
    "https://mirrors.cloud.tencent.com/pypi/simple/" # 腾讯云
)

# --- 颜色定义 ---
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m' # No Color

# --- 检查依赖 ---
command -v pip >/dev/null 2>&1 || { echo -e "${RED}错误: 'pip' 命令未找到。请先安装 Python 和 pip。${NC}"; exit 1; }
command -v curl >/dev/null 2>&1 || { echo -e "${RED}错误: 'curl' 命令未找到。请先安装 curl。${NC}"; exit 1; }


# --- 主要功能 ---

# 捕获脚本退出信号,确保执行清理函数
trap 'cleanup' EXIT

# 清理函数:卸载测试中安装的包
cleanup() {
    echo -e "\n${YELLOW}正在清理测试包 (${TEST_PACKAGE})...${NC}"
    # 隐藏卸载时的输出,除非出错
    pip uninstall -y "${TEST_PACKAGE}" > /dev/null 2>&1
    echo -e "${GREEN}清理完成。${NC}"
}

echo -e "${BLUE}将使用包 '${YELLOW}${TEST_PACKAGE}${NC}' 进行测试。${NC}"
echo -e "${BLUE}测试结束后,安装的包将被自动卸载。${NC}"

# 存储结果的数组
results=()

# 主循环,遍历所有待测试的源
for source in "${SOURCES[@]}"; do
    echo -e "\n${BLUE}==============================================================${NC}"
    echo -e "${YELLOW}正在测试源: ${GREEN}${source}${NC}"
    echo -e "${BLUE}==============================================================${NC}"

    # 1. 测试网络延迟 (Latency)
    # curl 到包的 simple 索引页面来测试延迟
    echo -e "${YELLOW}1. 正在测试网络延迟...${NC}"
    # curl -w: 定义输出格式; -o /dev/null: 不输出下载内容; -s: 静默模式; --max-time: 设置30秒超时
    latency_info=$(curl -w "time_connect=%{time_connect}s | time_starttransfer=%{time_starttransfer}s | time_total=%{time_total}s" -o /dev/null -s --max-time 30 "${source}${TEST_PACKAGE}/")
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}延迟测试成功: ${latency_info}${NC}"
        latency=$(echo $latency_info | awk -F'|' '{print $2}' | sed 's/time_starttransfer=//;s/s//')
    else
        echo -e "${RED}延迟测试失败,无法连接到 ${source} (30秒超时)${NC}"
        latency="N/A"
    fi

    # 2. 测试安装速度 (Install Speed)
    echo -e "\n${YELLOW}2. 正在测试包安装速度 (${TEST_PACKAGE})...${NC}"

    # 清理环境,确保测试公平
    echo "   - 清理旧包和缓存..."
    pip uninstall -y "${TEST_PACKAGE}" > /dev/null 2>&1
    pip cache purge > /dev/null 2>&1

    # 记录开始时间
    start_time=$(date +%s.%N)

    # 执行 pip install,使用 --index-url 临时指定源,并且禁用缓存,设置30秒超时
    install_output=$(pip install --index-url "${source}" --no-cache-dir --timeout 30 "${TEST_PACKAGE}" 2>&1)

    if [ $? -eq 0 ]; then
        # 记录结束时间
        end_time=$(date +%s.%N)
        # 计算耗时
        duration=$(echo "$end_time - $start_time" | bc)
        echo -e "${GREEN}安装成功!耗时: ${duration} 秒${NC}"
        install_time=$duration
    else
        # 检查是否是超时导致的失败
        if echo "$install_output" | grep -q "timeout"; then
            echo -e "${RED}安装超时 (30秒)!${NC}"
            install_time="Timeout"
        else
            echo -e "${RED}安装失败!${NC}"
            echo -e "${RED}错误信息: ${install_output}${NC}"
            install_time="Failed"
        fi
    fi

    # 将结果存入数组,用分号分隔
    results+=("${source};${latency};${install_time}")
done

# --- 结果总结 ---

echo -e "\n\n${BLUE}========================= 测试结果总结 ========================${NC}"
# 打印表头
printf "%-60s %-20s %-20s\n" "PyPI 源" "延迟 (s)" "安装耗时 (s)"
printf "%-60s %-20s %-20s\n" "------------------------------------------------------------" "--------------------" "--------------------"

# 对结果进行排序(按安装时间升序),并打印
# sort -t';' -k3 -n 表示以分号为分隔符,按第3个字段(安装时间)进行数值排序
(
for result in "${results[@]}"; do
    # 使用 IFS (Internal Field Separator) 来分割字符串
    IFS=';' read -r src lat inst <<< "$result"
    # 格式化输出
    printf "%-60s;%-20s;%-20s\n" "$src" "$lat" "$inst"
done
) | sort -t';' -k3 -n | while IFS=';' read -r src lat inst; do
    # 重新读取排序后的行并格式化打印
    printf "%-60s %-20s %-20s\n" "$src" "$lat" "$inst"
done

echo -e "${BLUE}==============================================================${NC}"
echo -e "${GREEN}测试完成!安装耗时越短越好。${NC}"

# cleanup 函数会在脚本退出时自动被调用,无需手动调用
exit 0

执行以下命令,即可测试 pip 镜像源的下行速度:

shell
bash test-pip-source.sh

可能的输出结果如下:

将使用包 'requests' 进行测试。
测试结束后,安装的包将被自动卸载。

==============================================================
正在测试源: https://pypi.org/simple/
==============================================================
1. 正在测试网络延迟...
延迟测试成功: time_connect=0.140368s | time_starttransfer=0.523468s | time_total=0.705317s

2. 正在测试包安装速度 (requests)...
   - 清理旧包和缓存...
安装成功!耗时: 4.264879000 秒

==============================================================
正在测试源: https://pypi.tuna.tsinghua.edu.cn/simple/
==============================================================
1. 正在测试网络延迟...
延迟测试成功: time_connect=0.112836s | time_starttransfer=0.223416s | time_total=0.324077s

2. 正在测试包安装速度 (requests)...
   - 清理旧包和缓存...
安装成功!耗时: 1.314596000 秒

==============================================================
正在测试源: https://mirrors.aliyun.com/pypi/simple/
==============================================================
1. 正在测试网络延迟...
延迟测试成功: time_connect=2.221697s | time_starttransfer=2.380867s | time_total=2.407094s

2. 正在测试包安装速度 (requests)...
   - 清理旧包和缓存...
安装成功!耗时: 6.639287000 秒

==============================================================
正在测试源: https://mirrors.ustc.edu.cn/pypi/simple/
==============================================================
1. 正在测试网络延迟...
延迟测试成功: time_connect=0.090017s | time_starttransfer=0.226905s | time_total=0.281726s

2. 正在测试包安装速度 (requests)...
   - 清理旧包和缓存...
安装成功!耗时: 1.123362000 秒

==============================================================
正在测试源: https://repo.huaweicloud.com/repository/pypi/simple/
==============================================================
1. 正在测试网络延迟...
延迟测试成功: time_connect=1.454980s | time_starttransfer=1.507713s | time_total=1.510921s

2. 正在测试包安装速度 (requests)...
   - 清理旧包和缓存...
安装成功!耗时: .859772000 秒

==============================================================
正在测试源: https://mirrors.cloud.tencent.com/pypi/simple/
==============================================================
1. 正在测试网络延迟...
延迟测试成功: time_connect=0.274309s | time_starttransfer=0.509947s | time_total=0.590346s

2. 正在测试包安装速度 (requests)...
   - 清理旧包和缓存...
安装成功!耗时: 1.474923000 秒


========================= 测试结果总结 ========================
PyPI 源                                                      延迟 (s)             安装耗时 (s) 
------------------------------------------------------------ -------------------- --------------------
https://repo.huaweicloud.com/repository/pypi/simple/          1.507713            .859772000          
https://mirrors.ustc.edu.cn/pypi/simple/                      0.226905            1.123362000         
https://pypi.tuna.tsinghua.edu.cn/simple/                     0.223416            1.314596000         
https://mirrors.cloud.tencent.com/pypi/simple/                0.509947            1.474923000         
https://pypi.org/simple/                                      0.523468            4.264879000         
https://mirrors.aliyun.com/pypi/simple/                       2.380867            6.639287000         
==============================================================
测试完成!安装耗时越短越好。

正在清理测试包 (requests)...
清理完成。