env.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. use std::{
  2. collections::HashMap,
  3. fmt,
  4. fs::File,
  5. io::{Read, Write},
  6. ops::{Deref, DerefMut},
  7. path::Path,
  8. };
  9. pub const ROOT_PATH: &str = "/";
  10. pub const ENV_FILE_PATH: &str = "/etc/profile";
  11. #[derive(Clone, Debug)]
  12. pub struct EnvEntry {
  13. /// 环境变量的名称
  14. name: String,
  15. /// 环境变量值的原始字符串,多个值之间使用':'分隔
  16. origin: String,
  17. /// 值分割后的集合
  18. collection: Vec<String>,
  19. }
  20. impl EnvEntry {
  21. pub fn new(env: String) -> Option<EnvEntry> {
  22. let split_result = env.split('=').collect::<Vec<&str>>();
  23. if split_result.len() != 2 || split_result.contains(&"") {
  24. return None;
  25. }
  26. let name = split_result.get(0).unwrap().to_string();
  27. let origin = split_result.get(1).unwrap().to_string();
  28. let collection = origin
  29. .split(':')
  30. .filter_map(|str| {
  31. let path = String::from(str);
  32. if Path::new(&path).is_dir() {
  33. Some(path)
  34. } else {
  35. None
  36. }
  37. })
  38. .collect::<Vec<String>>();
  39. Some(EnvEntry {
  40. name,
  41. origin,
  42. collection,
  43. })
  44. }
  45. #[allow(dead_code)]
  46. pub fn name(&self) -> &String {
  47. &self.name
  48. }
  49. pub fn origin(&self) -> &String {
  50. &self.origin
  51. }
  52. #[allow(dead_code)]
  53. pub fn collection(&self) -> &Vec<String> {
  54. &self.collection
  55. }
  56. }
  57. impl fmt::Display for EnvEntry {
  58. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  59. write!(f, "{}={}", self.name, self.origin)
  60. }
  61. }
  62. pub struct Env(HashMap<String, EnvEntry>);
  63. static mut ENV: Option<Env> = None;
  64. impl Deref for Env {
  65. type Target = HashMap<String, EnvEntry>;
  66. fn deref(&self) -> &Self::Target {
  67. &self.0
  68. }
  69. }
  70. impl DerefMut for Env {
  71. fn deref_mut(&mut self) -> &mut Self::Target {
  72. &mut self.0
  73. }
  74. }
  75. impl Env {
  76. /// 初始化环境变量结构体
  77. pub fn init() {
  78. // unsafe { ENV = Some(std::sync::Mutex::new(Env(HashMap::new()))) };
  79. unsafe { ENV = Some(Env(HashMap::new())) };
  80. Self::read_env();
  81. }
  82. /// 获取Env引用
  83. pub fn env() -> &'static mut Env {
  84. unsafe { ENV.as_mut().unwrap() }
  85. }
  86. /// 初始化环境变量文件
  87. pub fn init_envfile() {
  88. let mut file = File::create(ENV_FILE_PATH).unwrap();
  89. file.write_all("PATH=/bin:/usr/bin:/usr/local/bin\n".as_bytes())
  90. .unwrap();
  91. file.write_all("PWD=/\n".as_bytes()).unwrap();
  92. }
  93. /// 读取环境变量文件
  94. /// 如果文件不存在则创建
  95. pub fn read_env() {
  96. let env = unsafe { ENV.as_mut().unwrap() };
  97. if !Path::new(ENV_FILE_PATH).exists() {
  98. Env::init_envfile();
  99. }
  100. let mut file = File::open(ENV_FILE_PATH).unwrap();
  101. let mut buf: Vec<u8> = Vec::new();
  102. file.read_to_end(&mut buf).unwrap();
  103. for str in String::from_utf8(buf).unwrap().split('\n') {
  104. if let Some(entry) = EnvEntry::new(str.to_string()) {
  105. env.insert(entry.name.clone(), entry);
  106. }
  107. }
  108. }
  109. pub fn get(key: &String) -> Option<&EnvEntry> {
  110. let env = unsafe { ENV.as_ref().unwrap() };
  111. env.0.get(key)
  112. }
  113. pub fn insert(key: String, value: String) {
  114. if let Some(entry) = EnvEntry::new(value) {
  115. Self::env().insert(key, entry);
  116. }
  117. }
  118. /// 获取PATH环境变量的值(已分割)
  119. pub fn path() -> Vec<String> {
  120. let env = Self::env();
  121. env.get("PATH").unwrap().collection.clone()
  122. // paths
  123. // .split(':')
  124. // .filter_map(|str| {
  125. // let path = String::from(str);
  126. // if Path::new(&path).is_dir() {
  127. // Some(path)
  128. // } else {
  129. // None
  130. // }
  131. // })
  132. // .collect::<Vec<String>>()
  133. }
  134. pub fn current_dir() -> String {
  135. std::env::current_dir()
  136. .expect("Error getting current directory")
  137. .to_str()
  138. .unwrap()
  139. .to_string()
  140. }
  141. /// 从环境变量搜索路径,返回第一个匹配的绝对路径
  142. pub fn search_path_from_env(path: &String) -> Option<String> {
  143. let mut absolute_path = String::new();
  144. if !path.contains('/') {
  145. let mut dir_collection = Env::path();
  146. dir_collection.insert(0, Self::current_dir());
  147. for dir in dir_collection {
  148. let possible_path = format!("{}/{}", dir, path);
  149. if Path::new(&possible_path).is_file() {
  150. absolute_path = possible_path;
  151. break;
  152. }
  153. }
  154. if absolute_path.is_empty() {
  155. return None;
  156. } else {
  157. return Some(absolute_path);
  158. }
  159. } else if Path::new(path).exists() {
  160. return Some(path.clone());
  161. } else {
  162. return None;
  163. }
  164. }
  165. /// 返回所有环境变量的集合
  166. pub fn get_all() -> Vec<(String, String)> {
  167. let mut vec = Vec::new();
  168. for (name, entry) in Self::env().iter() {
  169. vec.push((name.clone(), entry.origin.clone()));
  170. }
  171. vec
  172. }
  173. }