在MacOS或者Linux中使用命令行进行一些操作或者执行一些脚本当用到curl命令时会经常出现这样的一些问题:
- 有部分链接需要使用代理才能访问到
- 如果设置了代理则很多不需要代理的链接访问速度会变得很慢
- 代理是按照流量收费的、不希望那些不需要代理的链接走代理通道
在系统代理中一般可以通过设置 PAC(Proxy auto-config) 脚本实现系统自动判断网络链接是否需要走代理,但是在命令行中由于curl没有JavaScript功能,因此curl不支持PAC实现自动代理。
原生curl虽然不支持pac,但是我们可以通过编写自定义脚本替代curl命令使得curl支持PAC功能。
在进行命令替换操作之前先安装 quickjs :
# homebrebrew
brew install quickjs
# Ubuntu 原生使用
# apt install quickjs
# 其他系统按各自方法安装
具体替换用的curl实现代码如下:
#!/bin/bash
# 优先使用 PAC_PATH
PAC_PATH=~/.hosts/pac.loc/pac.js
PAC_URL=http://127.0.0.1/pac.js
CURL_BINARY_PATH=/usr/local/opt/curl/bin/curl
QJS_BINARY_PATH=/usr/local/bin/qjs
# main
REQUEST_URI=""
SKIP_NEXT=false
ARGS=""
for arg in "$@"; do
ARGS="$ARGS $(sed -r 's:([() ;&~?]):\\\1:g' <<< "$arg")"
if [[ $SKIP_NEXT == true ]]; then
SKIP_NEXT=false
else
if [[ $arg =~ ^https?:// ]]; then
REQUEST_URI="$arg"
fi
fi
if [[ $arg == "--proxy" || $arg == "-x" ]]; then
SKIP_NEXT=true
fi
done
if [ "$REQUEST_URI" == "" ]; then
sh -c "$CURL_BINARY_PATH $ARGS"
else
SCRIPT="
$([ "$PAC_PATH" == "" ] && $CURL_BINARY_PATH -s $PAC_URL || cat "$PAC_PATH")
const args = '$REQUEST_URI'.match(/^[a-zA-Z]+:\/\/([^/]+)/);
const proxy = FindProxyForURL(...args);
if(proxy !== 'DIRECT') {
const [proto,host] = proxy.split(/[ ;]+/);
if(proto === 'SOCKS5') {
console.log('--proxy socks5h://' + host);
}
if(proto === 'PROXY') {
console.log('--proxy ' + host);
}
}
"
PROXY="$($QJS_BINARY_PATH -e "$SCRIPT")"
sh -c "$CURL_BINARY_PATH $PROXY $ARGS"
fi
将以上代码保存为 ~/.curl_with_pac.sh 并添加执行权限 chmod +x ~/.curl_with_pac.sh 。
然后编辑 ~/.zshrc 文件新增如下配置: (根据终端类型自己选择配置文件)
alias curl='~/.curl_with_pac.sh'
原文链接: 让curl支持PAC自动代理 – qnnp⁶