1 use std::{ 2 collections::HashMap, 3 fs::File, 4 io::{Read, Write}, 5 path::Path, 6 string::String, 7 vec::Vec, 8 }; 9 10 pub const ROOT_PATH: &str = "/"; 11 pub const ENV_FILE_PATH: &str = "/etc/profile"; 12 13 pub struct Env(std::collections::HashMap<String, String>); 14 15 lazy_static! { 16 static ref ENV: std::sync::Mutex<Env> = std::sync::Mutex::new(Env(HashMap::new())); 17 } 18 19 impl Env { 20 /// 初始化环境变量文件 21 pub fn init_envfile() { 22 let mut file = File::create(ENV_FILE_PATH).unwrap(); 23 file.write_all("PATH=/bin:/usr/bin:/usr/local/bin\n".as_bytes()) 24 .unwrap(); 25 file.write_all("PWD=/\n".as_bytes()).unwrap(); 26 } 27 28 /// 读取环境变量文件 29 /// 如果文件不存在则创建 30 pub fn read_env() { 31 let mut env = ENV.lock().unwrap(); 32 if !Path::new(ENV_FILE_PATH).exists() { 33 Env::init_envfile(); 34 } 35 let mut file = File::open(ENV_FILE_PATH).unwrap(); 36 let mut buf: Vec<u8> = Vec::new(); 37 file.read_to_end(&mut buf).unwrap(); 38 for (name, value) in String::from_utf8(buf) 39 .unwrap() 40 .split('\n') 41 .filter_map(|str| { 42 let v = str.split('=').collect::<Vec<&str>>(); 43 if v.len() == 2 && !v.contains(&"") { 44 Some((*v.get(0).unwrap(), *v.get(1).unwrap())) 45 } else { 46 None 47 } 48 }) 49 .collect::<Vec<(&str, &str)>>() 50 { 51 env.0.insert(String::from(name), String::from(value)); 52 } 53 } 54 55 pub fn get(key: &String) -> Option<String> { 56 let env = &mut ENV.lock().unwrap().0; 57 env.get(key).map(|value| value.clone()) 58 } 59 60 pub fn insert(key: String, value: String) { 61 ENV.lock().unwrap().0.insert(key, value); 62 } 63 64 pub fn path() -> Vec<String> { 65 let env = &ENV.lock().unwrap().0; 66 let paths = env.get("PATH").unwrap(); 67 paths 68 .split(':') 69 .filter_map(|str| { 70 let path = String::from(str); 71 if Path::new(&path).is_dir() { 72 Some(path) 73 } else { 74 None 75 } 76 }) 77 .collect::<Vec<String>>() 78 } 79 } 80