如果你想要在開發(fā)和生產(chǎn)模式下窥浪,高效的管理你的應用,那么你就需要理解什么是環(huán)境變量〉驯現(xiàn)在越來越多的Ruby工程師開始使用環(huán)境變量漾脂,但是可能有些人沒有真正的理解它是怎么工作的。這么文章將會告訴你胚鸯,環(huán)境變量是如何工作的骨稿,在什么情況下不能使用環(huán)境變量,并且還會介紹姜钳,如何在Rails應用中使用幾個最常用的管理環(huán)境變量的方法坦冠。
每個進程都擁有一組自己的環(huán)境變量
運行在服務器上的每一個程序,至少運行于一個進程之上哥桥。并且這些進程持有自己的一組環(huán)境變量蓝牲,其他進程不可以訪問。
可以理解的錯誤泰讽,初學者通常認為環(huán)境變量是服務器范圍內(nèi)使用的例衍。就像系統(tǒng)服務配置文件一樣。
進程和它的環(huán)境變量的生命周期是一樣的
環(huán)境變量是生命周期是和它所在的進程是一樣的已卸,也就是說佛玄,當你的應用的進程退出,重啟累澡,那么原先的環(huán)境變量就都會消失梦抢。
你可以通過在IRB 中設置環(huán)境變量來查看這個特性:
當進程退出的時候,環(huán)境變量也隨之消失了愧哟。
這就是為什么你的環(huán)境變量在你重啟服務或者退出shell的時候奥吩,消失的原因哼蛆。如果你想要環(huán)境變量有效的話,你就需要將它們存儲在想.bashrc這樣的配置文件當中霞赫。
子進程可以從父進程中繼承環(huán)境變量
每一個應用進程都會有一個父進程腮介,這是因為每個程序都是在其他程序中觸發(fā)啟動的。
如果你使用bash shell 打開 vim 端衰,那么vim的父進程就是這個shell叠洗。如果你的Rails應用是用了imagemagick去識別圖片,那么識別程序的父進程就是你的Rails應用旅东。
子進程從父進程中繼承環(huán)境變量灭抑。
在下面的例子中,我在IRB中設置了 環(huán)境變量$MARCO的值抵代,然后執(zhí)行輸出shell中環(huán)境變量的值腾节。
那么IRB就是我們創(chuàng)建的shell的父進程,然后它獲得了$MARCO環(huán)境變量的拷貝荤牍。
父進程可以定制環(huán)境變量給子進程
默認情況下禀倔,父進程會拷貝一份環(huán)境變量到子進程中,不過它還可以参淫,從命令行你可以使用env命令救湖,或者設置環(huán)境變量的特殊語法去設置傳遞給子進程的環(huán)境變量。
子進程不可以修改它的父進程的環(huán)境變量
上面已經(jīng)提到了涎才,子進程只是獲得了父進程的環(huán)境變量的拷貝而不是引用鞋既,所以通過下面的例子我們可以看到,修改子進程的環(huán)境變量的值耍铜,相應在父進程中沒有變化邑闺。
環(huán)境變量的改變不會同步到其他進程中
環(huán)境變量是存儲在進程空間的,也就是表明棕兼,運行相同程序的兩個進程的環(huán)境變量的變化不會相互影響陡舅。
環(huán)境變量與shell變量是不同的
環(huán)境變量和本地變量經(jīng)常被搞混,shell為自己提供了一個 本地的變量系統(tǒng)伴挚,在語法上shell變量和環(huán)境變量的用法是一樣的靶衍,但是shell變量不會被拷貝到子進程中去。
下面是一個例子茎芋,首頁使用在命令行中設置了一個本地變量(shell變量)的值颅眶,然后通過Ruby命令訪問環(huán)境變量哈希中與之同名的變量,結(jié)果返回是找不到的田弥,然后再使用export 對本地變量進行轉(zhuǎn)換后它就可以在環(huán)境變量中被訪問了涛酗。
管理環(huán)境變量實踐
假設我們有兩個Rails 應用同時運行在同一個服務器上,然后這兩個應用又同樣需要訪問第三方的API_KEY ,我們可以將這個第三方API_KEY存放在環(huán)境變量中商叹。但是如何為他們設置不同的值呢燕刻。
看完上面的介紹,想必你也知道了剖笙,環(huán)境變量與服務器上的兩個Rails應用一樣是運行在不同的進程當中的卵洗,所以它們是獨立的,可以被分別設置枯途,那現(xiàn)在剩下的問題就是如何設置這個環(huán)境變量的值了忌怎。
Figaro
當你安裝完Figaro到Rails應用之后籍滴,在config/application.yml中的鍵值對酪夷,都將會在應用啟動的時候被加載進ruby的ENV中。
安裝gem:
# Gemfile
gem "figaro"
然后添加鍵值對到 application.yml孽惰。注意一定要將這個文件添加到.gitignore中以防止重要的信息被提交到代碼倉庫中晚岭。
# config/application.yml
API_KEY: 12345
Dotenv
dotenv 與Figaro非常的相似,除了它是從.env文件中加載的環(huán)境變量勋功,而不是YAML中坦报。
安裝:
# Gemfile
gem "dotenv"
然后添加配置信息到.env文件中,與上面一樣狂鞋,.env文件也要加到到.gitignore中片择。
# .env
API_KEY=12345
在Rails中就可以使用ENV哈希訪問它了。
ENV['API_KEY']
你還可以像下面這樣骚揍,在shell中運行命令加載預定于的環(huán)境變量:
dotenv ./my_script.sh
Secrets.yml?
抱歉雖然Secrets.yml很酷字管,但他并不會設置環(huán)境變量,所以它其實不是Figoaro和dotev這樣的Gem的替代方案信不。