@@ -47,6 +47,7 @@ pub struct Settings {
4747 pub pgroup : Option < HashSet < u64 > > ,
4848 pub session : Option < HashSet < u64 > > ,
4949 pub cgroup : Option < HashSet < String > > ,
50+ pub env : Option < HashSet < String > > ,
5051 pub threads : bool ,
5152
5253 pub pidfile : Option < String > ,
@@ -111,6 +112,9 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> {
111112 cgroup : matches
112113 . get_many :: < String > ( "cgroup" )
113114 . map ( |groups| groups. cloned ( ) . collect ( ) ) ,
115+ env : matches
116+ . get_many :: < String > ( "env" )
117+ . map ( |env_vars| env_vars. cloned ( ) . collect ( ) ) ,
114118 threads : false ,
115119 pidfile : matches. get_one :: < String > ( "pidfile" ) . cloned ( ) ,
116120 logpidfile : matches. get_flag ( "logpidfile" ) ,
@@ -129,6 +133,7 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> {
129133 && settings. pgroup . is_none ( )
130134 && settings. session . is_none ( )
131135 && settings. cgroup . is_none ( )
136+ && settings. env . is_none ( )
132137 && !settings. require_handler
133138 && settings. pidfile . is_none ( )
134139 && pattern. is_empty ( )
@@ -279,6 +284,22 @@ fn collect_matched_pids(settings: &Settings) -> UResult<Vec<ProcessInformation>>
279284 pid. cgroup_v2_path ( ) . unwrap_or ( "/" . to_string ( ) ) ,
280285 ) ;
281286
287+ let env_matched = match & settings. env {
288+ Some ( env_filters) => {
289+ let env_vars = pid. env_vars ( ) . unwrap_or_default ( ) ;
290+ env_filters. iter ( ) . any ( |filter| {
291+ if let Some ( ( key, expected_value) ) = filter. split_once ( '=' ) {
292+ // Match specific key=value pair
293+ env_vars. get ( key) == Some ( & expected_value. to_string ( ) )
294+ } else {
295+ // Match key existence only
296+ env_vars. contains_key ( filter)
297+ }
298+ } )
299+ }
300+ None => true ,
301+ } ;
302+
282303 let ids_matched = any_matches ( & settings. uid , pid. uid ( ) . unwrap ( ) )
283304 && any_matches ( & settings. euid , pid. euid ( ) . unwrap ( ) )
284305 && any_matches ( & settings. gid , pid. gid ( ) . unwrap ( ) ) ;
@@ -311,6 +332,7 @@ fn collect_matched_pids(settings: &Settings) -> UResult<Vec<ProcessInformation>>
311332 && pgroup_matched
312333 && session_matched
313334 && cgroup_matched
335+ && env_matched
314336 && ids_matched
315337 && handler_matched
316338 && pidfile_matched)
@@ -530,6 +552,7 @@ pub fn clap_args(pattern_help: &'static str, enable_v_flag: bool) -> Vec<Arg> {
530552 arg!( -r --runstates <state> "match runstates [D,S,Z,...]" ) ,
531553 arg!( -A --"ignore-ancestors" "exclude our ancestors from results" ) ,
532554 arg!( --cgroup <grp> "match by cgroup v2 names" ) . value_delimiter( ',' ) ,
555+ arg!( --env <"name[=val],..." > "match on environment variable" ) . value_delimiter( ',' ) ,
533556 // arg!(--ns <PID> "match the processes that belong to the same namespace as <pid>"),
534557 // arg!(--nslist <ns> "list which namespaces will be considered for the --ns option.")
535558 // .value_delimiter(',')
0 commit comments