Rust 使用 dotenv 來設定環境變數

pro發表於2022-01-22

在專案中,我們通常需要設定一些環境變數,用來儲存一些憑證或其它資料,這時我們可以使用 dotenv 這個 crate。

 

首先在專案中新增 dotenv 這個依賴:

7 
8 
9 
dependencies] 
dotenv = " 
o. 15.0"

 

例如在下面這個專案中,需要設定資料庫連線字串和 Debug 等級這兩個環境變數。在開發環境下,我們可以在專案根目錄下建立 .env 這個檔案:

EXPLORER 
v OPEN EDITORS 
x .env 
v LEARN 
v src 
@ main.rs 
target 
h! env 
.gitignore 
Cargo.lock 
Cargo.toml

 

在 .env 檔案裡,我們設定兩個環境變數,分別是 DB_URL 和 LOG_LEVEL:

:argo.toml U 
.env U X 
.env 
1 
2 
DB_URL=postgres : // user : pwd@locathost : 5432/mydb 
LOG LEVEL-DEBUGI

 

下面來到 main.rs,想要訪問系統的環境變數,我們使用標準庫的 std::env 即可:

main.rs > 
use std env; 
fn main() { 
for (k, v) in env::vars() { 
print In! ("PATH: { } " , 
env :: var( " PATH" ) . unwrap( ) ) ; 
print In! ("DB: {I" , 
env :: var( "DB_URL"). unwrap()); 
println!("LOG: O" , 
env :: var( " LOG _ LEVEL " ) . unwrap( ) ) ;

這裡,我們先把獲取到的環境變數進行遍歷和列印,然後再分別嘗試列印 PATH、DB_URL 和 LOG_LEVEL 這三個環境變數的值。

 

結果如下:

USER: solenovex 
XPC FLAGS: exe 
XPC SERVICE NAME: e 
/Users/s01enovex/ . cargo/ bin/ cargo 
CE CONDA: 
CE M: 
_CFBund1eIdentifier: com.apple.Terminal 
CF USER TEXT ENCODING: 
PATH: /Users/s01enovex/.cargo/bin: / Users/ solenovex/opt/anaconda3 
bin : /Users/s01enovex/opt/anaconda3/condabin : /Users/s01enovex/ . car 
go/bin: /usr/local/bin : /usr/bin : / bin : /usr/sbin : /sbin : /usr/local/go 
/ bin : /usr/local/share/dotnet : N/ . dotnet/tools : / Users/ solenovex/go/ 
bin 
thread Imainl panicked at I called 
on an 'Err' 
src/main.rs:9:43 
value: NotPresentI, 
note: run with 'RUST BACKTRACE-I' 
environment variable to display 
a backtrace

我們可以看到,前面是遍歷列印的環境變數,後邊列印出了 PATH 的值。然後在嘗試獲取 DB_URL 值的時候程式就恐慌了,因為沒有找到這個環境變數。

 

現在我們使用 dotenv 這個 crate:

use std ::env; 
use dotenv dotenv; 
fn main() { 
dotenv().ok(); 
for (k, v) in env:: vars() { 
println ! ( " { } : 
print In! ( 
print In! ( 
print In! ( 
" PATH: 0" , 
env :: var( " PATH" ) . unwrap( ) ) ; 
"DB: 
env :: var( "DB_URL") . unwrap( ) ) ; 
" LOG: 0", 
env :: var( " LOG _ LEVEL " ) . unwrap( ) ) ;

先把 dotenv 匯入,然後在程式開始的地方執行 dotenv() 函式即可,這就會從當前目錄或父目錄中的 .env 檔案中載入環境變數。

如果你想指定其它路徑,可以使用 crate 中提供的 from_filename 或 from_path 這兩個函式。

 

好,那麼呼叫 dotenv() 之後為什麼還要呼叫 ok() 方法?

首先,dotenv() 返回的是 Result<PathBuf> 型別,如果返回值不使用的話,就會發出一個警告:

fn main() { 
dotenv(); 
for 
print In! ( 
vars() {

呼叫 ok() 之後,會把 Result 轉化為 Option,而 Option 就不會產生未使用 Result 的警告了。

 

那麼,為什麼不使用 unwrap()?

因為在生產環境中,你不會使用 .env 這個檔案,你應該使用真實的環境變數,這時 dotenv() 函式就會載入失敗,如果使用 unwrap(),那麼你的程式就會停止執行。

所以這裡使用 ok() 的目的就是當載入 dotenv 環境檔案失敗的時候可以忽略錯誤。

 

程式碼:

 1 use std::env;
 2 use dotenv::dotenv;
 3 
 4 fn main() {
 5     dotenv().ok();
 6 
 7     for (k, v) in env::vars() {
 8         println!("{}: {}", k, v);
 9     }
10 
11     println!("PATH: {}", env::var("PATH").unwrap());
12     println!("DB: {}", env::var("DB_URL").unwrap());
13     println!("LOG: {}", env::var("LOG_LEVEL").unwrap());
14 }

 

相關文章