pidof: allow to suppress output

Often pidof is used in shell scripts in this form:

    if pidof daemon >/dev/null; then
        ...
    fi

The redirection to /dev/null is needed because otherwise the script
would output the found PIDs.
Let's add a -q option which, similary to grep, just sets the exit code.
Also exit on first match, as there is no reason to proceed further when
at least a process is matched.

Tested with:

    $ ./pidof bash
    17701 14019 5276 2967
    $ echo $?
    0
    $ ./pidof bashx
    $ echo $?
    1
    $ ./pidof -q bash
    $ echo $?
    0
    $ ./pidof -q bashx
    $ echo $?
    1
This commit is contained in:
Matteo Croce 2019-03-19 14:33:01 +01:00 committed by Craig Small
parent 79097e55e4
commit b067ecc886
2 changed files with 24 additions and 15 deletions

14
pidof.1
View File

@ -15,17 +15,17 @@
.\" along with this program; if not, write to the Free Software .\" along with this program; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA .\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
.\" .\"
.TH PIDOF 1 "2020-06-04" "" "User Commands" .TH PIDOF 1 "2020-12-22" "" "User Commands"
.SH NAME .SH NAME
pidof -- find the process ID of a running program pidof -- find the process ID of a running program
.SH SYNOPSIS .SH SYNOPSIS
.B pidof .B pidof
.RB [ \-s ] .RB [ \-s ]
.RB [ \-c ] .RB [ \-c ]
.RB [ \-q ]
.RB [ \-w ]
.RB [ \-x ] .RB [ \-x ]
.RB [ \-o .RB [ \-o
.IR omitpid[,omitpid...] ]
.RB [ \-o
.IR omitpid[,omitpid...]... ] .IR omitpid[,omitpid...]... ]
.RB [ \-S .RB [ \-S
.IR separator ] .IR separator ]
@ -42,12 +42,14 @@ Single shot - this instructs the program to only return one \fIpid\fP.
Only return process ids that are running with the same root directory. Only return process ids that are running with the same root directory.
This option is ignored for non-root users, as they will be unable to check This option is ignored for non-root users, as they will be unable to check
the current root directory of processes they do not own. the current root directory of processes they do not own.
.IP \-x .IP \-q
Scripts too - this causes the program to also return process id's of Quiet mode, suppress any output and only sets the exit status accordingly.
shells running the named scripts.
.IP \-w .IP \-w
Show also processes that do not have visible command line (e.g. kernel Show also processes that do not have visible command line (e.g. kernel
worker threads). worker threads).
.IP \-x
Scripts too - this causes the program to also return process id's of
shells running the named scripts.
.IP "-o \fIomitpid\fP" .IP "-o \fIomitpid\fP"
Tells \fIpidof\fP to omit processes with that process id. The special Tells \fIpidof\fP to omit processes with that process id. The special
pid \fB%PPID\fP can be used to name the parent process of the \fIpidof\fP pid \fB%PPID\fP can be used to name the parent process of the \fIpidof\fP

15
pidof.c
View File

@ -56,7 +56,7 @@ static int opt_single_shot = 0; /* -s */
static int opt_scripts_too = 0; /* -x */ static int opt_scripts_too = 0; /* -x */
static int opt_rootdir_check = 0; /* -c */ static int opt_rootdir_check = 0; /* -c */
static int opt_with_workers = 0; /* -w */ static int opt_with_workers = 0; /* -w */
static int opt_quiet = 0; /* -q */
static char *pidof_root = NULL; static char *pidof_root = NULL;
@ -70,8 +70,9 @@ static int __attribute__ ((__noreturn__)) usage(int opt)
fputs(USAGE_OPTIONS, fp); fputs(USAGE_OPTIONS, fp);
fputs(_(" -s, --single-shot return one PID only\n"), fp); fputs(_(" -s, --single-shot return one PID only\n"), fp);
fputs(_(" -c, --check-root omit processes with different root\n"), fp); fputs(_(" -c, --check-root omit processes with different root\n"), fp);
fputs(_(" -x also find shells running the named scripts\n"), fp); fputs(_(" -q, quiet mode, only set the exit code\n"), fp);
fputs(_(" -w, --with-workers show kernel workers too\n"), fp); fputs(_(" -w, --with-workers show kernel workers too\n"), fp);
fputs(_(" -x also find shells running the named scripts\n"), fp);
fputs(_(" -o, --omit-pid <PID,...> omit processes with PID\n"), fp); fputs(_(" -o, --omit-pid <PID,...> omit processes with PID\n"), fp);
fputs(_(" -S, --separator SEP use SEP as separator put between PIDs"), fp); fputs(_(" -S, --separator SEP use SEP as separator put between PIDs"), fp);
fputs(USAGE_SEPARATOR, fp); fputs(USAGE_SEPARATOR, fp);
@ -294,13 +295,14 @@ int main (int argc, char **argv)
int first_pid = 1; int first_pid = 1;
const char *separator = " "; const char *separator = " ";
const char *opts = "scnxwmo:S:?Vh"; const char *opts = "scnqxwmo:S:?Vh";
static const struct option longopts[] = { static const struct option longopts[] = {
{"check-root", no_argument, NULL, 'c'}, {"check-root", no_argument, NULL, 'c'},
{"single-shot", no_argument, NULL, 's'}, {"single-shot", no_argument, NULL, 's'},
{"omit-pid", required_argument, NULL, 'o'}, {"omit-pid", required_argument, NULL, 'o'},
{"separator", required_argument, NULL, 'S'}, {"separator", required_argument, NULL, 'S'},
{"quiet", no_argument, NULL, 'q'},
{"with-workers", no_argument, NULL, 'w'}, {"with-workers", no_argument, NULL, 'w'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'V'},
@ -318,6 +320,9 @@ int main (int argc, char **argv)
/* process command-line options */ /* process command-line options */
while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != -1) { while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != -1) {
switch (opt) { switch (opt) {
case 'q':
opt_quiet = 1;
/* fallthrough */
case 's': case 's':
opt_single_shot = 1; opt_single_shot = 1;
break; break;
@ -372,12 +377,14 @@ int main (int argc, char **argv)
found = 1; found = 1;
for (i = proc_count - 1; i >= 0; i--) { /* and display their PIDs */ for (i = proc_count - 1; i >= 0; i--) { /* and display their PIDs */
if (!opt_quiet) {
if (first_pid) { if (first_pid) {
first_pid = 0; first_pid = 0;
printf ("%ld", (long) procs[i].pid); printf ("%ld", (long) procs[i].pid);
} else { } else {
printf ("%s%ld", separator, (long) procs[i].pid); printf ("%s%ld", separator, (long) procs[i].pid);
} }
}
if (opt_single_shot) break; if (opt_single_shot) break;
} }
@ -386,7 +393,7 @@ int main (int argc, char **argv)
} }
/* final line feed */ /* final line feed */
if (found) printf("\n"); if (!opt_quiet && found) printf("\n");
/* some cleaning */ /* some cleaning */
safe_free(procs); safe_free(procs);