Repository: uutils/procps
Pull request #206 (2024-08-28 15:48:47)

pidof: adapt options to those of `pidof` from `procps-ng`
I thought a bit about `pidof` and I think our implementation should match the `pidof` from `procps-ng`, and not the one from `sysvinit` that comes with Debian (there is a pending [proposal](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=810018) to switch to the `pidof` from `procps-ng`).

And so this PR adapts the options to those of the `pidof` from `procps-ng`. The functionality of the options seems to be the same, so no changes there. 

Before the changes:
```
Options:
  -d <sep>          Use the provided character as output separator
  -o <omitpid>      Omit results with a given PID
  -q                Quiet mode. Do not display output
  -s                Only return one PID
  -h, --help        Print help
  -V, --version     Print version
```

After the changes:
```
Options:
  -S, --separator <SEP>  Use SEP as separator between PIDs
  -o, --omit-pid <PID>   Omit results with a given PID
  -q                     Quiet mode. Do not display output
  -s, --single-shot      Only return one PID
  -h, --help             Print help
  -V, --version          Print version
```


Patch:
diff --git a/src/uu/pidof/src/pidof.rs b/src/uu/pidof/src/pidof.rs
index 9b34fa4..d11c686 100644
--- a/src/uu/pidof/src/pidof.rs
+++ b/src/uu/pidof/src/pidof.rs
@@ -17,7 +17,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
     let matches = uu_app().try_get_matches_from(args)?;
 
     let arg_program_name = matches.get_many::<String>("program-name");
-    let arg_separator = matches.get_one::<String>("d").unwrap();
+    let arg_separator = matches.get_one::<String>("S").unwrap();
 
     if arg_program_name.is_none() {
         uucore::error::set_exit_code(1);
@@ -124,11 +124,14 @@ pub fn uu_app() -> Command {
         //         .action(ArgAction::SetTrue),
         // )
         .arg(
-            Arg::new("d")
-                .short('d')
-                .help("Use the provided character as output separator")
+            Arg::new("S")
+                .short('S')
+                // the pidof bundled with Debian uses -d instead of -S
+                .visible_short_alias('d')
+                .long("separator")
+                .help("Use SEP as separator between PIDs")
                 .action(ArgAction::Set)
-                .value_name("sep")
+                .value_name("SEP")
                 .default_value(" ")
                 .hide_default_value(true),
         )
@@ -141,11 +144,12 @@ pub fn uu_app() -> Command {
         .arg(
             Arg::new("o")
                 .short('o')
+                .long("omit-pid")
                 .help("Omit results with a given PID")
                 .value_delimiter(',')
                 .action(ArgAction::Append)
                 .value_parser(clap::value_parser!(usize))
-                .value_name("omitpid"),
+                .value_name("PID"),
         )
         .arg(
             Arg::new("q")
@@ -156,6 +160,7 @@ pub fn uu_app() -> Command {
         .arg(
             Arg::new("s")
                 .short('s')
+                .long("single-shot")
                 .help("Only return one PID")
                 .action(ArgAction::SetTrue),
         )


Test patch:
diff --git a/tests/by-util/test_pidof.rs b/tests/by-util/test_pidof.rs
index 94f6e5f..96e88e2 100644
--- a/tests/by-util/test_pidof.rs
+++ b/tests/by-util/test_pidof.rs
@@ -42,17 +42,40 @@ fn test_quiet() {
 
 #[test]
 #[cfg(target_os = "linux")]
-fn test_s_flag() {
-    let binding = new_ucmd!()
-        .args(&["-s", "kthreadd", "kthreadd", "kthreadd"])
-        .succeeds();
-    let output = binding.stdout_str().trim_end();
+fn test_single_shot() {
+    for arg in ["-s", "--single-shot"] {
+        let binding = new_ucmd!()
+            .args(&[arg, "kthreadd", "kthreadd", "kthreadd"])
+            .succeeds();
+        let output = binding.stdout_str().trim_end();
 
-    let pids = output.split(' ').collect::<Vec<_>>();
-    let first = pids[0];
+        let pids = output.split(' ').collect::<Vec<_>>();
+        let first = pids[0];
 
-    let result = pids.iter().all(|it| *it == first);
+        let result = pids.iter().all(|it| *it == first);
 
-    assert!(result);
-    assert_eq!(pids.len(), 3);
+        assert!(result);
+        assert_eq!(pids.len(), 3);
+    }
+}
+
+#[test]
+#[cfg(target_os = "linux")]
+fn test_omit_pid() {
+    for arg in ["-o=1000", "--omit-pid=1000"] {
+        new_ucmd!().arg(arg).arg("kthreadd").succeeds();
+    }
+}
+
+#[test]
+#[cfg(target_os = "linux")]
+fn test_separator() {
+    use regex::Regex;
+
+    for arg in ["-S", "-d", "--separator"] {
+        new_ucmd!()
+            .args(&[arg, "separator", "kthreadd", "kthreadd"])
+            .succeeds()
+            .stdout_matches(&Regex::new("^[1-9][0-9]*separator[1-9][0-9]*\n$").unwrap());
+    }
 }