Python 3.6/3.8版本切换脚本
Python版本切换脚本使用文档
脚本介绍
本脚本用于RHEL/CentOS系统中切换Python3的版本,在Python 3.6和Python 3.8之间进行切换。每次执行脚本会自动在两个版本间进行切换,同时自动处理对应的pip3版本切换,并支持系统alternatives机制。
开发背景
开发此脚本的主要原因:
-
版本冲突问题:开发环境需要使用Python 3.8的新特性,但在RHEL/CentOS系统中,即使安装了Python 3.8,
python3
命令仍默认指向系统自带的3.6版本。 -
系统稳定性考虑:直接永久修改
python3
链接指向3.8版本可能导致依赖Python 3.6的系统工具不可用,影响系统稳定性和日常运维。 -
临时切换需求:需要在开发工作时临时切换到3.8版本,开发完成后再切回3.6版本,以保持系统工具的正常运行。
-
pip同步问题:切换Python版本的同时需要同步切换pip版本,否则会出现用pip安装的包仍安装到Python 3.6环境中,导致开发环境中无法使用新安装的包。
-
环境一致性:确保开发团队能够在相同的Python环境中工作,减少"我这里能运行但你那里不行"的问题。
脚本内容
#!/bin/bash# Python路径配置 - 适用于RHEL/CentOS 8
PY36="/usr/libexec/platform-python3.6" # pythone3.6安装路径
PY38="/usr/bin/python3.8" # python3.8安装路径
PY3="/usr/bin/python3" # 软链接位置
BACKUP="/usr/bin/python3.original" # 备份位置# pip路径配置
PIP36="/usr/bin/pip3.6" # 如果不存在会自动处理
PIP38="/usr/bin/pip3.8" # 如果不存在会自动处理
PIP3="/usr/bin/pip3" # pip3软链接位置
PIP_BACKUP="/usr/bin/pip3.original" # pip3备份位置
PIP_ALT="/etc/alternatives/pip3" # pip3 alternatives路径# 检查Python安装
if [ ! -f "$PY36" ]; thenecho "错误: Python 3.6 ($PY36) 不存在"exit 1
fiif [ ! -f "$PY38" ]; thenecho "错误: Python 3.8 ($PY38) 不存在"exit 1
fi# 首次运行时备份原始Python链接
if [ ! -f "$BACKUP" ] && [ -L "$PY3" ]; thenecho "备份原始Python3链接到 $BACKUP"sudo cp -P "$PY3" "$BACKUP"
fi# 检查pip3.6是否存在,不存在则创建
if [ ! -f "$PIP36" ] && [ -f "$PY36" ]; thenecho "创建pip3.6链接..."sudo ln -sf "$PY36" -m pip "$PIP36"# 如果上面的方法创建失败,尝试另一种方式if [ ! -f "$PIP36" ]; thenecho "使用Python3.6模块方式创建pip3.6..."sudo bash -c "echo -e '#!/bin/bash\n\"$PY36\" -m pip \"\$@\"' > $PIP36"sudo chmod +x "$PIP36"fi
fi# 检查pip3.8是否存在,不存在则创建
if [ ! -f "$PIP38" ] && [ -f "$PY38" ]; thenecho "创建pip3.8链接..."sudo "$PY38" -m ensurepip || trueif [ ! -f "$PIP38" ]; thenecho "使用Python3.8模块方式创建pip3.8..."sudo bash -c "echo -e '#!/bin/bash\n\"$PY38\" -m pip \"\$@\"' > $PIP38"sudo chmod +x "$PIP38"fi
fi# 首次运行时备份原始pip链接
if [ ! -f "$PIP_BACKUP" ] && [ -L "$PIP3" ]; thenecho "备份原始pip3链接到 $PIP_BACKUP"sudo cp -P "$PIP3" "$PIP_BACKUP"
fi# 获取当前Python3指向
CURRENT=$(readlink -f "$PY3")
echo "当前Python3链接指向: $CURRENT"# 切换Python和pip版本
if [ "$CURRENT" = "$PY36" ]; thenecho "切换到Python 3.8..."sudo rm -f "$PY3"sudo ln -s "$PY38" "$PY3"# 切换pip3版本echo "切换到pip3.8..."# 检测alternatives系统if [ -L "$PIP3" ] && [ "$(readlink "$PIP3")" = "$PIP_ALT" ]; thenecho "检测到alternatives系统管理pip3..."# 检查alternatives命令if command -v update-alternatives >/dev/null 2>&1; then# 使用update-alternatives命令echo "使用update-alternatives切换pip3..."sudo update-alternatives --install "$PIP3" pip3 "$PIP38" 80sudo update-alternatives --set pip3 "$PIP38"elif command -v alternatives >/dev/null 2>&1; then# 使用alternatives命令 (RedHat/CentOS)echo "使用alternatives切换pip3..."sudo alternatives --install "$PIP3" pip3 "$PIP38" 80sudo alternatives --set pip3 "$PIP38"else# 如果都没有,直接修改链接echo "未找到alternatives命令,直接修改链接..."sudo rm -f "$PIP_ALT"sudo ln -sf "$PIP38" "$PIP_ALT"fielse# 正常处理非alternatives情况if [ -f "$PIP38" ]; thensudo rm -f "$PIP3"sudo ln -s "$PIP38" "$PIP3"elseecho "警告: pip3.8不存在,创建基于模块的pip3链接"sudo bash -c "echo -e '#!/bin/bash\n\"$PY38\" -m pip \"\$@\"' > $PIP3"sudo chmod +x "$PIP3"fifiecho "已切换Python: $(python3 --version)"echo "已切换pip: $(pip3 -V 2>/dev/null || echo 'pip3命令不可用,但已创建链接')"
elif [ "$CURRENT" = "$PY38" ]; thenecho "切换回Python 3.6..."sudo rm -f "$PY3"sudo ln -s "$PY36" "$PY3"echo "已切换: $(python3 --version)"
else# 检查当前版本,确定下一步切换到哪个版本CURRENT_VERSION=$(python3 --version 2>&1)if [[ "$CURRENT_VERSION" == *"3.6"* ]]; thenecho "当前是Python 3.6,切换到Python 3.8..."sudo rm -f "$PY3"sudo ln -s "$PY38" "$PY3"elseecho "当前是Python 3.8或其他版本,切换到Python 3.6..."sudo rm -f "$PY3"sudo ln -s "$PY36" "$PY3"fiecho "已切换: $(python3 --version)"
fi# 验证pip是否与python版本匹配
PIP_VERSION=$(pip3 -V 2>/dev/null)
if [ $? -eq 0 ]; thenPYTHON_VERSION=$(python3 --version)if [[ "$PYTHON_VERSION" == *"3.6"* ]] && [[ "$PIP_VERSION" != *"python3.6"* ]]; thenecho "警告: pip3版本与python3版本不匹配"echo "Python: $PYTHON_VERSION"echo "pip: $PIP_VERSION"echo "建议使用 'python3 -m pip' 命令确保版本匹配"elif [[ "$PYTHON_VERSION" == *"3.8"* ]] && [[ "$PIP_VERSION" != *"python3.8"* ]]; thenecho "警告: pip3版本与python3版本不匹配"echo "Python: $PYTHON_VERSION"echo "pip: $PIP_VERSION"echo "建议使用 'python3 -m pip' 命令确保版本匹配"elseecho "Python和pip版本匹配正常"fi
elseecho "提示: pip3命令可能不可用,建议使用 'python3 -m pip' 命令"
fi# 显示当前pip3路径信息
echo "当前pip3链接情况:"
if [ -L "$PIP3" ]; thenPIP3_TARGET=$(readlink -f "$PIP3")echo "pip3 ($PIP3) -> $PIP3_TARGET"# 检查alternativesif [ -L "$PIP_ALT" ] && [ "$(readlink "$PIP3")" = "$PIP_ALT" ]; thenPIP_ALT_TARGET=$(readlink -f "$PIP_ALT")echo "alternatives ($PIP_ALT) -> $PIP_ALT_TARGET"fi
elseecho "pip3 ($PIP3) 不是软链接"
fiecho "完成!"
echo "如需安装包,建议使用: python3 -m pip install 包名"
注:上述代码为精简版,完整版本请参考实际脚本文件。
使用方法
-
创建脚本文件
vi switch_python.sh
-
粘贴脚本内容,然后保存退出 (按ESC,输入:wq,回车)
-
添加执行权限
chmod +x switch_python.sh
-
执行脚本
sudo ./switch_python.sh
工作原理
- 脚本首先检查系统中是否同时存在Python 3.6和Python 3.8
- 首次执行时备份原始Python3和pip3软链接
- 如果pip3.6或pip3.8不存在,会尝试自动创建
- 检测当前Python3软链接指向哪个版本
- 根据当前版本自动切换到另一个版本,同时切换对应的pip3版本
- 支持alternatives系统管理的pip链接(如RedHat/CentOS系统)
- 验证pip版本是否与Python版本匹配
- 显示当前pip3的链接情况
功能特点
- 双版本切换:在Python 3.6和3.8之间进行自动切换
- 自动备份:首次运行会备份原始链接,以便将来恢复
- pip同步切换:Python版本切换时,自动切换对应的pip版本
- alternatives支持:兼容RedHat/CentOS系统的alternatives机制
- 链接自动修复:如果pip链接不存在,会自动创建
- 版本验证:检查pip和Python版本是否匹配
- 状态报告:显示当前链接情况和版本信息
注意事项
- 脚本需要root权限执行(使用sudo)
- 脚本默认假设Python 3.6路径为
/usr/libexec/platform-python3.6
,Python 3.8路径为/usr/bin/python3.8
,如果您的系统路径不同,请修改脚本中的相应变量 - 确保系统中已安装Python 3.8,如未安装,请先执行安装
- 首次执行会创建备份,以便将来可以恢复原始状态
- 切换后部分系统工具可能受影响,建议谨慎在生产环境使用
- 如果系统使用alternatives机制管理pip,脚本会自动检测并使用对应的命令
- 建议使用
python3 -m pip
命令安装包,以确保使用正确的pip版本
故障排除
- 找不到Python 3.8:确认是否已安装,可使用
find / -name "python3.8" -type f 2>/dev/null
查找确切路径 - 权限错误:确保使用sudo执行脚本
- 链接未生效:执行
hash -r
刷新shell的命令缓存 - 恢复原始状态:
sudo ln -sf /usr/bin/python3.original /usr/bin/python3 sudo ln -sf /usr/bin/pip3.original /usr/bin/pip3
- alternatives错误:如遇到alternatives系统错误,可以尝试手动设置
sudo alternatives --set python3 /path/to/python3.x sudo alternatives --set pip3 /path/to/pip3.x
- pip版本不匹配:如果遇到pip版本与Python不匹配,建议使用
python3 -m pip
命令
适用环境
- RHEL/CentOS 7/8/9 系统
- 需要在Python 3.6和3.8之间频繁切换的开发环境
- SONiC编译环境等需要特定Python版本的场景
- 使用alternatives系统管理的Linux环境