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
.\" 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
pidof -- find the process ID of a running program
.SH SYNOPSIS
.B pidof
.RB [ \-s ]
.RB [ \-c ]
.RB [ \-q ]
.RB [ \-w ]
.RB [ \-x ]
.RB [ \-o
.IR omitpid[,omitpid...] ]
.RB [ \-o
.IR omitpid[,omitpid...]... ]
.RB [ \-S
.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.
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.
.IP \-x
Scripts too - this causes the program to also return process id's of
shells running the named scripts.
.IP \-q
Quiet mode, suppress any output and only sets the exit status accordingly.
.IP \-w
Show also processes that do not have visible command line (e.g. kernel
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"
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

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