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