MacOS系统上,升级python3.12时,超级慢,而且最后还失败了。看了日志,发现是用curl从raw.githubusercontent.com上下载Python安装包超时了。
解决方案一:开启翻墙工具,穿越围墙
解决方案二:使用raw.gitmirror.com替换raw.githubusercontent.com
翻墙有风险,操作需谨慎,这里我采用的是方案二。
1. 查看curl路径
which curl
# /usr/bin/curl
2. 编写自定义脚本,并赋予执行权限
ln -s `which curl` /usr/local/bin/curl
[ -d ~/.local/bin ] || mkdir -p ~/.local/bin/
cd ~/.local/bin
touch curl
chmod +x curl
# 注:PATH要配置到.bashrc或.zshrc里,别的窗口才能起作用
export PATH=$HOME/.local/bin:$PATH
vi curl
which curl
# ~/.local/bin/curl
3. 脚本内容
#!/usr/bin/env python
import os,sys
origin,target="raw.githubusercontent.com","raw.gitmirror.com"
args=" ".join(repr(i) if " " in i else i for i in sys.argv[1:])
cmd="/usr/bin/{} ".format(sys.argv[0].split('/')[-1])+args.replace(origin,target)
sys.exit(os.system(cmd))
4. 测试效果
curl https://raw.githubusercontent.com/Homebrew/homebrew-core/a775cbd0967da13128293d71fb26431fdedee6fb/Formula/m/mpdecimal.rb
5. 重新执行升级命令(这时候就很快了,不到一分钟就下载完毕,十分钟内就完成升级)
brew upgrade python@3.12
注: wget也可以用类似的方法加速
################# 2024.02.08 补充:
如果有外网服务器,还可以配个中转请求:
本地curl文件内容如下(需export JUMPER_IP='<服务器IP地址>')
#!/usr/bin/env python
import os
import systry:from typing import List # NOQA:F401
except ImportError:passdef gen_cmd(sys_argv):# type: (List[str]) -> strargs = []scheme = "https://"origin, target = "raw.githubusercontent.com", "raw.gitmirror.com"domains = ("objects.githubusercontent.com", "github.com")redirect = os.getenv("JUMPER_IP")host = "http://{}:9337/".format(redirect)for i in sys_argv[1:]:if i.startswith(scheme):j = i[len(scheme) :]if j.startswith(origin):i = i.replace(origin, target)elif redirect:for domain in domains:if j.startswith(domain):i = host + jbreakelif " " in i:i = repr(i)args.append(i)tool = "/usr/local/bin/" + sys_argv[0].split("/")[-1]cmd = tool + " " + " ".join(args)return cmddef main():# type: () -> intsys_argv = sys.argvif "--dry" in sys_argv:sys_argv = [i for i in sys_argv if i != "--dry"]print("--> " + gen_cmd(sys_argv))return 0return os.system(gen_cmd(sys_argv))if __name__ == "__main__":sys.exit(main())
服务器上的app.py文件如下:
# pip install httpx orjson sanic gunicorn 'uvicorn[standard]'
from httpx import AsyncClient
from orjson import dumps, loads
from sanic import Sanic, rawapp = Sanic("Jumper", dumps=dumps, loads=loads)@app.route("/<full:path>")
async def handler(request, full: str):host, url = full.lstrip("/"), ""try:host, url = host.split("/", 1)except ValueError:passif host.startswith("http"):scheme, domain = host.split(".", 1)else:scheme, domain = "https", hostasync with AsyncClient(base_url=scheme + "://" + domain) as client:r = await client.get(url + "?" + request.query_string)return raw(r.content)if __name__ == "__main__":app.run()
后台启动服务:
gunicorn app:app --bind 0.0.0.0:9337 --worker-class uvicorn.workers.UvicornWorker --daemon