diff --git a/src/uu/ps/src/process_selection.rs b/src/uu/ps/src/process_selection.rs index fc67ae85..5bf89f9f 100644 --- a/src/uu/ps/src/process_selection.rs +++ b/src/uu/ps/src/process_selection.rs @@ -49,6 +49,8 @@ pub struct ProcessSelectionSettings { /// - `-C` Select by command name pub command_names: Option>, + /// - `-q, --quick-pid` Quick process selection by PID + pub quick_pids: Option>, /// - `-p, --pid` Select specific process IDs pub pids: Option>, /// - `--ppid` Select specific parent process IDs @@ -81,6 +83,9 @@ impl ProcessSelectionSettings { command_names: matches .get_many::>("command") .map(|xs| xs.flatten().cloned().collect()), + quick_pids: matches + .get_many::>("quick-pid") + .map(|xs| xs.flatten().copied().collect()), pids: matches .get_many::>("pid") .map(|xs| xs.flatten().copied().collect()), @@ -108,6 +113,18 @@ impl ProcessSelectionSettings { } pub fn select_processes(self) -> UResult> { + if let Some(ref quick_pids) = self.quick_pids { + let mut selected = Vec::new(); + for &pid in quick_pids { + if let Ok(process) = + ProcessInformation::try_new(std::path::PathBuf::from(format!("/proc/{}", pid))) + { + selected.push(process); + } + } + return Ok(selected); + } + let mut current_process = ProcessInformation::current_process_info().unwrap(); let current_tty = current_process.tty(); let current_euid = current_process.euid().unwrap(); diff --git a/src/uu/ps/src/ps.rs b/src/uu/ps/src/ps.rs index 32f016ca..671b3f27 100644 --- a/src/uu/ps/src/ps.rs +++ b/src/uu/ps/src/ps.rs @@ -379,12 +379,12 @@ pub fn uu_app() -> Command { .value_parser(parse_uid_list) .help("select by effective user ID (EUID) or name"), ) - // .args([ - // Arg::new("pPID").long("ppid").help("parent process id"), - // Arg::new("qPID") - // .short('q') - // .long("quick-pid") - // .help("process id"), - // Arg::new("t").short('t').long("tty").help("terminal"), - // ]) + .arg( + Arg::new("quick-pid") + .short('q') + .long("quick-pid") + .action(ArgAction::Append) + .value_parser(parse_numeric_list) + .help("quick process selection by PID"), + ) } diff --git a/tests/by-util/test_ps.rs b/tests/by-util/test_ps.rs index de997e71..03ffd7ae 100644 --- a/tests/by-util/test_ps.rs +++ b/tests/by-util/test_ps.rs @@ -230,7 +230,7 @@ fn test_command_name_selection() { #[test] #[cfg(target_os = "linux")] -fn test_pid_selection() { +fn test_pid_and_quick_pid_selection() { let our_pid = std::process::id(); // Test that only pid 1 and pid of the test runner is present let test = |pid_args: &[&str]| { @@ -243,24 +243,24 @@ fn test_pid_selection() { .stdout_matches(&match_regex); }; - for flag in ["-p", "--pid"] { + for flag in ["-p", "--pid", "-q", "--quick-pid"] { test(&[flag, &format!("1 {our_pid}")]); test(&[flag, &format!("1,{our_pid}")]); test(&[flag, "1", flag, &our_pid.to_string()]); - } - // Test nonexistent PID - new_ucmd!() - .args(&["-p", "0", "--no-headers"]) - .fails() - .code_is(1) - .no_output(); + // Test nonexistent PID + new_ucmd!() + .args(&[flag, "0", "--no-headers"]) + .fails() + .code_is(1) + .no_output(); - // Test invalid PID - new_ucmd!() - .args(&["-p", "invalid"]) - .fails() - .stderr_contains("invalid number"); + // Test invalid PID + new_ucmd!() + .args(&[flag, "invalid"]) + .fails() + .stderr_contains("invalid number"); + } } #[test]