網上的教程大多只講了想要在命令行中使用代理需要輸入哪些命令,比如這個export http_proxy=http://127.0.0.1:8080
,通常情況下這應該已經可以用了,不過有時卻不能成功完成任務。本文中,我想根據自己的一些粗淺的經驗,講講其背后的原理是什么。(本文適用於類Unix系統)

一、環境變量
首先來說明一下環境變量是什么。在操作系統中有許多進程,進程之間進行信息交流的其中一種途徑就是環境變量。環境變量是一個鍵值對的集合,進程從父進程中收到環境變量,可以添加或修改其中的一些值,再在創建子進程時將環境變量傳給子進程。export
指令便是修改環境變量的指令,並且指定這個修改是要傳給子進程的,如果不使用export
而單用key=value
這樣一行指令,則僅修改當前Shell進程的環境變量而不傳給子進程。
通過這樣一條export
指令,現在只要是用當前Shell啟動的子進程,便可以在自己的環境變量里看到http_proxy -> http://127.0.0.1:8080這樣的一個映射關系了,其實這個環境變量就像是貼在牆上的小廣告,上面寫着【你想進行http
訪問嗎?如果你想的話,在127.0.0.1:8080這個位置有一個代理服務點,這個站點可以使用http代理協議】。子進程看到了它,可以選擇尊重這個環境變量,在進行http訪問的時候將流量交給127.0.0.1:8080轉發。子進程也可以選擇拒絕遵從這個環境變量,還是原樣直接訪問,但是一般的程序都會選擇遵從的。
二、環境變量名
接下來講解環境變量名,例子中是http_proxy
,它的含義是指示進程在進行http
協議訪問時盡量走代理,請看下面的例子:
$ export http_proxy=http://127.0.0.1:8080
$ curl http://ip8.com/ip
<返回代理服務器的ip>
$ curl https://ip8.com/ip
<返回本機的ip>
在這個例子中,curl在進行http
訪問時(curl http://ip8.com/ip)尊重了環境變量的指示,在進行https
訪問時(curl https://ip8.com/ip)因為沒有對應的指示,便直接連接了。
比較常用的環境變量名字有http_proxy
,https_proxy
,ftp_proxy
,all_proxy
,其中特殊的是all_proxy
,它指定了全部協議都可以通過這個代理,它的優先級要低於其他變量。
比如說http_proxy
和all_proxy
都有設置,curl在進行http
訪問的時候會通過http_proxy指定的代理,在進行https_proxy訪問的時候會首先嘗試通過https_proxy
指定的代理,但是並沒有設置,於是就去通過了all_proxy
指定的代理。
另外,有的應用可能會去讀取HTTP_PROXY
等等大寫的環境變量,而忽略小寫環境變量,可能需要特別注意,可以大小寫的同時設置保證兼容性。
三、代理協議
下面來說一下http://
的含義,它指示的是與代理服務通信時使用的協議,使用http代理協議並不是只能傳遞http協議請求,它就像是【http代理服務器您好,這里有一個https請求,地址是www.baidu.com,內容是...,請幫我轉發】這樣的句式,可以傳遞的內容是廣泛的。
比較常見的代理協議有http:// https:// socks:// ss:// ssr:// vmess://
之類的。
絕大部分程序都會支持http://
協議的代理,大部分程序會支持socks://
協議,只有專用的軟件才支持ss:// ssr:// vmess://
並經常把它們轉接成http:// socks://
協議以供其他應用使用。
四、推薦配置
通過前面的講解大概已經了解了命令行應用代理的工作原理,那么應該怎么設置呢?之前提到http代理協議的兼容性最好,所以訪問http_proxy一般設為http代理,而socks協議用途最廣,可以將all_proxy設為socks協議,socks協議還有一點注意的是,可以用socks5h://
來替代socks://
,這樣可以讓域名解析在代理服務器進行,防止DNS污染。
綜上,我推薦的配置是:(端口與提供代理服務的軟件開放的端口一致)
export http_proxy=http://127.0.0.1:8080
export HTTP_PROXY=http://127.0.0.1:8080
export https_proxy=http://127.0.0.1:8080
export HTTPS_PROXY=http://127.0.0.1:8080
export all_proxy=socks5h://127.0.0.1:1080
export ALL_PROXY=socks5h://127.0.0.1:1080
也可以將其寫入~/.bashrc等文件來自動配置或配置一個alias來給這一大段命令一個別稱,方便手動激活。
參考
https://unix.stackexchange.com/questions/71144/what-do-the-bash-builtins-set-and-export-do
https://github.com/urllib3/urllib3/issues/1035