@@ -49,18 +49,33 @@ fn match_process_name(
4949 process : & mut ProcessInformation ,
5050 name_to_match : & str ,
5151 with_workers : bool ,
52+ match_scripts : bool ,
5253) -> bool {
5354 let binding = process. cmdline . split ( ' ' ) . collect :: < Vec < _ > > ( ) ;
54- let mut path = binding. first ( ) . unwrap ( ) . to_string ( ) ;
55+ let path = binding. first ( ) . unwrap ( ) . to_string ( ) ;
5556
5657 if path. is_empty ( ) {
5758 if !with_workers {
5859 return false ;
5960 }
60- path . clone_from ( & process . status ( ) [ "Name" ] ) ;
61+ return process . name ( ) . unwrap ( ) == name_to_match ;
6162 } ;
6263
63- PathBuf :: from ( path) . file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) == name_to_match
64+ if PathBuf :: from ( path) . file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) == name_to_match {
65+ return true ;
66+ }
67+
68+ // When a script (ie. file starting with e.g. #!/bin/sh) is run like `./script.sh`, then
69+ // its cmdline will look like `/bin/sh ./script.sh` but its .name() will be `script.sh`.
70+ // As name() gets truncated to 15 characters, the original pidof seems to always do a prefix match.
71+ if match_scripts && binding. len ( ) > 1 {
72+ return PathBuf :: from ( binding[ 1 ] )
73+ . file_name ( )
74+ . map ( |f| f. to_str ( ) . unwrap ( ) )
75+ . is_some_and ( |f| f == name_to_match && f. starts_with ( & process. name ( ) . unwrap ( ) ) ) ;
76+ }
77+
78+ false
6479}
6580
6681fn collect_matched_pids ( matches : & ArgMatches ) -> Vec < usize > {
@@ -70,6 +85,7 @@ fn collect_matched_pids(matches: &ArgMatches) -> Vec<usize> {
7085 . cloned ( )
7186 . collect ( ) ;
7287 let with_workers = matches. get_flag ( "with-workers" ) ;
88+ let match_scripts = matches. get_flag ( "x" ) ;
7389
7490 let collected = walk_process ( ) . collect :: < Vec < _ > > ( ) ;
7591 let arg_omit_pid = matches
@@ -83,7 +99,8 @@ fn collect_matched_pids(matches: &ArgMatches) -> Vec<usize> {
8399 . flat_map ( |program| {
84100 let mut processed = Vec :: new ( ) ;
85101 for mut process in collected. clone ( ) {
86- let contains = match_process_name ( & mut process, & program, with_workers) ;
102+ let contains =
103+ match_process_name ( & mut process, & program, with_workers, match_scripts) ;
87104 let should_omit = arg_omit_pid. contains ( & process. pid ) ;
88105
89106 if contains && !should_omit {
@@ -184,10 +201,10 @@ pub fn uu_app() -> Command {
184201 . help ( "Show kernel worker threads as well" )
185202 . action ( ArgAction :: SetTrue ) ,
186203 )
187- // .arg(
188- // Arg::new("x")
189- // .short('x')
190- // .help("Return PIDs of shells running scripts with a matching name")
191- // .action(ArgAction::SetTrue),
192- // )
204+ . arg (
205+ Arg :: new ( "x" )
206+ . short ( 'x' )
207+ . help ( "Return PIDs of shells running scripts with a matching name" )
208+ . action ( ArgAction :: SetTrue ) ,
209+ )
193210}
0 commit comments