背景
CentOS 7.9 默认自带的 Python 版本为 2.7.x,该版本已于 2020 年 1 月 1 日停止维护,不支持现代 Python 特性(如 f-string 语法),无法直接运行高版本 Python 脚本。此外,Python 2.7 存在安全风险,建议升级到 Python 3(如 3.6 或更高版本)以确保兼容性和安全性。本文档记录了在 CentOS 7.9 上升级到 Python 3.6 的过程,解决无法编译运行高版本 Python 脚本的问题,并配置定时任务以自动化运行脚本。
问题描述
我运行在Ubuntu系统运行成功的 Python 脚本(dify_workflow.py)使用了 f-string 语法(例如 f"Bearer {DIFY_API_KEY}"),该语法仅在 Python 3.6 及以上版本支持。尝试在 CentOS 7.9 的默认 Python 2.7 环境下运行时,报错:
SyntaxError: invalid syntax
此外,脚本依赖 requests 模块,但 Python 2.7 环境中未安装该模块。尝试通过 yum 安装依赖时,遇到网络问题(Could not resolve host: mirrorlist.centos.org),因为 CentOS 7 已于 2024 年 6 月 30 日达到 EOL,官方镜像源 mirrorlist.centos.org 失效。
排查与解决方案
以下是排查问题的步骤和最终解决方案。
步骤 1:尝试使用 Python 2.7 运行脚本
思路:修改脚本以兼容 Python 2.7,替换 f-string 为 .format() 方法,并添加编码声明以支持中文字符。
操作:
-
修改脚本(
dy_dify_workflow.py)为 Python 2.7 兼容版本:# -*- coding: utf-8 -*- import requests import json from datetime import datetime DIFY_API_URL = "http://IP/v1/workflows/run" DIFY_API_KEY = "app-aBLQF950nP" def dify_workflow(): headers = { "Authorization": "Bearer {}".format(DIFY_API_KEY), "Content-Type": "application/json" } payload = { "inputs": {}, "response_mode": "blocking", "user": "cron-user" } try: response = requests.post(DIFY_API_URL, headers=headers, json=payload) response.raise_for_status() print u"工作流触发成功: {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) print u"服务器响应: {}".format(response.text) except requests.RequestException as e: print u"工作流触发失败: {}".format(str(e)) if e.response is not None: print u"服务器响应: {}".format(e.response.text) else: print u"无服务器响应,可能为网络问题" if __name__ == "__main__": dify_workflow() -
保存脚本并确保文件编码为 UTF-8:
file /home/osadmin/workflow/dy_dify_workflow.py iconv -t UTF-8 /home/osadmin/workflow/dy_dify_workflow.py -o /home/osadmin/workflow/dy_dify_workflow_utf8.py mv /home/osadmin/workflow/dy_dify_workflow_utf8.py /home/osadmin/workflow/dy_dify_workflow.py -
尝试运行:
python /home/osadmin/workflow/dy_dify_workflow.py
问题:
- 报错
ImportError: No module named requests,表明缺少requests模块。 - 尝试安装
requests时,yum无法连接到mirrorlist.centos.org。
结论:Python 2.7 虽可通过修改语法兼容脚本,但安装依赖受限,且长期使用不安全,决定升级到 Python 3.6。
步骤 2:修复 Yum 仓库配置
思路:由于 CentOS 7 EOL,mirrorlist.centos.org 失效,需将 yum 仓库切换到归档源 vault.centos.org。同时,检查多个 .repo 文件以解决仓库冲突。
操作:
-
检查现有
.repo文件:ls /etc/yum.repos.d/输出:
CentOS-Base.repo CentOS-SCLo-scl.repo CentOS-SCLo-scl-rh.repo docker-ce.repo epel.repo epel-testing.repo es.repo发现多个
.repo文件,可能导致Repository base is listed more than once错误。 -
备份
.repo文件:sudo mkdir /etc/yum.repos.d/backup sudo mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ -
创建新的
CentOS-Base.repo:sudo vi /etc/yum.repos.d/CentOS-Base.repo添加:
[base] name=CentOS-$releasever - Base baseurl=http://vault.centos.org/7.9.2009/os/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [updates] name=CentOS-$releasever - Updates baseurl=http://vault.centos.org/7.9.2009/updates/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [extras] name=CentOS-$releasever - Extras baseurl=http://vault.centos.org/7.9.2009/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 -
创建新的
CentOS-SCLo-scl-rh.repo:sudo vi /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo添加:
[centos-sclo-rh] name=CentOS-$releasever - SCLo rh baseurl=http://vault.centos.org/7.9.2009/sclo/$basearch/rh/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 enabled=1 -
禁用第三方仓库:
sudo yum-config-manager --disable centos-trinasolar docker-ce-stable epel epel-testing es -
清理并重建 Yum 缓存:
sudo yum clean all sudo yum makecache -
验证仓库:
sudo yum repolist确认列出
base、updates、extras和centos-sclo-rh。
问题:
-
如果仍报
Could not resolve host,检查网络:ping 114.114.114.114 ping vault.centos.org cat /etc/resolv.conf-
确保
/etc/resolv.conf包含:nameserver 8.8.8.8 nameserver 114.114.114.114 -
配置代理(if needed):
sudo vi /etc/yum.conf添加:
proxy=http://<proxy-host>:<proxy-port> proxy_username=<username> proxy_password=<password>
-
步骤 3:安装 Python 3.6
思路:使用 centos-sclo-rh 仓库安装 python36。
操作:
-
安装 Python 3.6 及其依赖:
sudo yum install -y centos-release-scl sudo yum install -y python36 python36-devel python36-pip -
验证安装:
/usr/bin/python3.6 --version /usr/bin/python3.6 -m pip --version输出示例:
Python 3.6.8 pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6)
步骤 4:安装依赖模块
思路:使用 pip 安装脚本所需的 requests 模块。
操作:
-
升级
pip:/usr/bin/python3.6 -m pip install --upgrade pip -
安装
requests:/usr/bin/python3.6 -m pip install requests -
验证:
/usr/bin/python3.6 -c "import requests; print(requests.__version__)"输出示例:
2.31.0。
步骤 5:测试脚本
思路:使用原脚本(支持 f-string),直接在 /usr/bin/python3.6 下运行。
操作:
-
保存脚本到
/home/osadmin/workflow/dy_dify_workflow.py:# -*- coding: utf-8 -*- import requests import json from datetime import datetime DIFY_API_URL = "http://10.12.242.7/v1/workflows/run" DIFY_API_KEY = "app-aBLQcurXYoSx3t3XF1F950nP" def dy_dify_workflow(): headers = { "Authorization": f"Bearer {DIFY_API_KEY}", "Content-Type": "application/json" } payload = { "inputs": {}, "response_mode": "blocking", "user": "cron-user" } try: response = requests.post(DIFY_API_URL, headers=headers, json=payload) response.raise_for_status() print(f"工作流触发成功: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print(f"服务器响应: {response.text}") except requests.RequestException as e: print(f"工作流触发失败: {str(e)}") if e.response is not None: print(f"服务器响应: {e.response.text}") else: print("无服务器响应,可能为网络问题") if __name__ == "__main__": dy_dify_workflow() -
确保文件编码为 UTF-8:
file /home/osadmin/workflow/dy_dify_workflow.py -
测试运行:
/usr/bin/python3.6 /home/osadmin/workflow/dy_dify_workflow.py
步骤 6:配置定时任务
思路:使用 cron 设置每小时运行脚本。
操作:
-
编辑 crontab:
crontab -e -
添加任务:
0 * * * * /usr/bin/python3.6 /home/osadmin/workflow/dy_dify_workflow.py >> /home/osadmin/workflow/cron.log 2>&1 -
验证:
crontab -l cat /home/osadmin/workflow/cron.log -
确保权限:
chmod +x /home/osadmin/workflow/dy_dify_workflow.py chown osadmin:osadmin /home/osadmin/workflow/dy_dify_workflow.py
步骤 7:检查脚本网络
思路:确保脚本可以访问目标 URL(http://10.12.242.7)。
操作:
-
测试网络:
ping 10.12.242.7 curl -I http://10.12.242.7/v1/workflows/run -
如果不通,检查防火墙或 SELinux:
sudo firewall-cmd --list-all sudo firewall-cmd --add-port=80/tcp --permanent sudo firewall-cmd --reload sudo setenforce 0 # 临时禁用 SELinux
总结
通过以下步骤,成功解决了 CentOS 7.9 自带 Python 2.7 无法运行高版本脚本的问题:
- 尝试修改脚本兼容 Python 2.7,但受限于依赖安装和安全性问题。
- 修复
yum仓库,切换到vault.centos.org,并处理多个.repo文件的冲突。 - 安装 Python 3.6,直接使用
/usr/bin/python3.6运行脚本。 - 安装
pip和requests模块。 - 配置 cron 定时任务,自动化运行脚本。
此方案避免了虚拟环境,直接使用系统级 Python 3.6,简化了配置,同时确保了脚本的兼容性和稳定性。
注意事项
- Python 2.7 风险:继续使用 Python 2.7 可能存在安全漏洞,强烈建议长期使用 Python 3.6 或更高版本。
-
网络维护:定期检查 DNS 和代理配置,确保
yum可用。 -
日志监控:定期查看
/home/osadmin/workflow/cron.log以排查脚本运行问题。
如需进一步优化(如使用虚拟环境或升级到 Python 3.8),可参考如何使用虚拟环境安装python环境。