new -o option: only the oldest that matches
This commit is contained in:
parent
7f68f2504c
commit
501e740a31
1
NEWS
1
NEWS
@ -5,6 +5,7 @@ better (?) RPM generation
|
|||||||
XConsole and top.desktop removed
|
XConsole and top.desktop removed
|
||||||
old build system removed
|
old build system removed
|
||||||
code cleanup
|
code cleanup
|
||||||
|
pgrep and pkill get "-o" (oldest matching process)
|
||||||
|
|
||||||
procps-3.0.3 --> procps-3.0.4
|
procps-3.0.3 --> procps-3.0.4
|
||||||
|
|
||||||
|
1
TODO
1
TODO
@ -1,6 +1,7 @@
|
|||||||
-------------------------- general ------------------------
|
-------------------------- general ------------------------
|
||||||
|
|
||||||
Implement /usr/proc/bin tools like Solaris has.
|
Implement /usr/proc/bin tools like Solaris has.
|
||||||
|
The prstat command is interesting, like top in batch mode.
|
||||||
|
|
||||||
Don't these really belong in the procps package?
|
Don't these really belong in the procps package?
|
||||||
killall pstree fuser lsof who
|
killall pstree fuser lsof who
|
||||||
|
12
pgrep.1
12
pgrep.1
@ -7,13 +7,13 @@
|
|||||||
pgrep, pkill \- look up or signal processes based on name and other attributes
|
pgrep, pkill \- look up or signal processes based on name and other attributes
|
||||||
|
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
pgrep [\-flnvx] [\-d \fIdelimiter\fP] [\-P \fIppid\fP,...] [\-g \fIpgrp\fP,...]
|
pgrep [\-flvx] [\-d \fIdelimiter\fP] [\-n|\-o] [\-P \fIppid\fP,...] [\-g \fIpgrp\fP,...]
|
||||||
.br
|
.br
|
||||||
[\-s \fIsid\fP,...] [\-u \fIeuid\fP,...] [\-U \fIuid\fP,...] [\-G \fIgid\fP,...]
|
[\-s \fIsid\fP,...] [\-u \fIeuid\fP,...] [\-U \fIuid\fP,...] [\-G \fIgid\fP,...]
|
||||||
.br
|
.br
|
||||||
[\-t \fIterm\fP,...] [\fIpattern\fP]
|
[\-t \fIterm\fP,...] [\fIpattern\fP]
|
||||||
|
|
||||||
pkill [\-\fIsignal\fP] [\-fnvx] [\-P \fIppid\fP,...] [\-g \fIpgrp\fP,...]
|
pkill [\-\fIsignal\fP] [\-fvx] [\-n|\-o] [\-P \fIppid\fP,...] [\-g \fIpgrp\fP,...]
|
||||||
.br
|
.br
|
||||||
[\-s \fIsid\fP,...] [\-u \fIeuid\fP,...] [\-U \fIuid\fP,...] [\-G \fIgid\fP,...]
|
[\-s \fIsid\fP,...] [\-u \fIeuid\fP,...] [\-U \fIuid\fP,...] [\-G \fIgid\fP,...]
|
||||||
.br
|
.br
|
||||||
@ -61,6 +61,10 @@ List the process name as well as the process ID. (\fBpgrep\fP only.)
|
|||||||
Select only the newest (most recently started) of the matching
|
Select only the newest (most recently started) of the matching
|
||||||
processes.
|
processes.
|
||||||
.TP
|
.TP
|
||||||
|
\-o
|
||||||
|
Select only the oldest (least recently started) of the matching
|
||||||
|
processes.
|
||||||
|
.TP
|
||||||
\-P \fIppid\fP,...
|
\-P \fIppid\fP,...
|
||||||
Only match processes whose parent process ID is listed.
|
Only match processes whose parent process ID is listed.
|
||||||
.TP
|
.TP
|
||||||
@ -137,8 +141,8 @@ The running \fBpgrep\fP or \fBpkill\fP process will never report
|
|||||||
itself as a match.
|
itself as a match.
|
||||||
|
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
The options \-n and \-v can not be combined. Let me know if you need
|
The options \-n and \-o and \-v can not be combined. Let me know if
|
||||||
to do this.
|
you need to do this.
|
||||||
|
|
||||||
Defunct processes are reported.
|
Defunct processes are reported.
|
||||||
|
|
||||||
|
49
pgrep.c
49
pgrep.c
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -39,6 +40,7 @@ union el {
|
|||||||
|
|
||||||
static int opt_full = 0;
|
static int opt_full = 0;
|
||||||
static int opt_long = 0;
|
static int opt_long = 0;
|
||||||
|
static int opt_oldest = 0;
|
||||||
static int opt_newest = 0;
|
static int opt_newest = 0;
|
||||||
static int opt_negate = 0;
|
static int opt_negate = 0;
|
||||||
static int opt_exact = 0;
|
static int opt_exact = 0;
|
||||||
@ -72,10 +74,10 @@ static int
|
|||||||
usage (int opt)
|
usage (int opt)
|
||||||
{
|
{
|
||||||
if (i_am_pkill)
|
if (i_am_pkill)
|
||||||
fprintf (stderr, "Usage: pkill [-SIGNAL] [-fnvx] ");
|
fprintf (stderr, "Usage: pkill [-SIGNAL] [-fvx] ");
|
||||||
else
|
else
|
||||||
fprintf (stderr, "Usage: pgrep [-flnvx] [-d DELIM] ");
|
fprintf (stderr, "Usage: pgrep [-flvx] [-d DELIM] ");
|
||||||
fprintf (stderr, "[-P PPIDLIST] [-g PGRPLIST] [-s SIDLIST]\n"
|
fprintf (stderr, "[-n|-o] [-P PPIDLIST] [-g PGRPLIST] [-s SIDLIST]\n"
|
||||||
"\t[-u EUIDLIST] [-U UIDLIST] [-G GIDLIST] [-t TERMLIST] "
|
"\t[-u EUIDLIST] [-U UIDLIST] [-G GIDLIST] [-t TERMLIST] "
|
||||||
"[PATTERN]\n");
|
"[PATTERN]\n");
|
||||||
exit (opt == '?' ? 0 : 2);
|
exit (opt == '?' ? 0 : 2);
|
||||||
@ -111,7 +113,7 @@ parse_opts (int argc, char **argv)
|
|||||||
strcat (opts, "ld:");
|
strcat (opts, "ld:");
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat (opts, "fnvxP:g:s:u:U:G:t:?V");
|
strcat (opts, "fnovxP:g:s:u:U:G:t:?V");
|
||||||
|
|
||||||
while ((opt = getopt (argc, argv, opts)) != -1) {
|
while ((opt = getopt (argc, argv, opts)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
@ -122,10 +124,20 @@ parse_opts (int argc, char **argv)
|
|||||||
opt_long = 1;
|
opt_long = 1;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
|
if (opt_oldest|opt_negate|opt_newest)
|
||||||
|
usage (opt);
|
||||||
opt_newest = 1;
|
opt_newest = 1;
|
||||||
++criteria_count;
|
++criteria_count;
|
||||||
break;
|
break;
|
||||||
|
case 'o':
|
||||||
|
if (opt_oldest|opt_negate|opt_newest)
|
||||||
|
usage (opt);
|
||||||
|
opt_oldest = 1;
|
||||||
|
++criteria_count;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
|
if (opt_oldest|opt_negate|opt_newest)
|
||||||
|
usage (opt);
|
||||||
opt_negate = 1;
|
opt_negate = 1;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
@ -478,8 +490,8 @@ select_procs (void)
|
|||||||
{
|
{
|
||||||
PROCTAB *ptp;
|
PROCTAB *ptp;
|
||||||
proc_t task;
|
proc_t task;
|
||||||
unsigned long long newest_start_time = 0;
|
unsigned long long saved_start_time; // for new/old support
|
||||||
pid_t newest_pid = 0;
|
pid_t saved_pid = 0; // for new/old support
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
int size = 32;
|
int size = 32;
|
||||||
regex_t *preg;
|
regex_t *preg;
|
||||||
@ -494,13 +506,20 @@ select_procs (void)
|
|||||||
ptp = do_openproc ();
|
ptp = do_openproc ();
|
||||||
preg = do_regcomp ();
|
preg = do_regcomp ();
|
||||||
|
|
||||||
|
if (opt_newest) saved_start_time = 0ULL;
|
||||||
|
if (opt_oldest) saved_start_time = ~0ULL;
|
||||||
|
if (opt_newest) saved_pid = 0;
|
||||||
|
if (opt_oldest) saved_pid = INT_MAX;
|
||||||
|
|
||||||
memset (&task, 0, sizeof (task));
|
memset (&task, 0, sizeof (task));
|
||||||
while (readproc (ptp, &task)) {
|
while (readproc (ptp, &task)) {
|
||||||
int match = 1;
|
int match = 1;
|
||||||
|
|
||||||
if (task.pid == myself)
|
if (task.pid == myself)
|
||||||
continue;
|
continue;
|
||||||
else if (opt_newest && task.start_time < newest_start_time)
|
else if (opt_newest && task.start_time < saved_start_time)
|
||||||
|
match = 0;
|
||||||
|
else if (opt_oldest && task.start_time > saved_start_time)
|
||||||
match = 0;
|
match = 0;
|
||||||
else if (opt_ppid && ! match_numlist (task.ppid, opt_ppid))
|
else if (opt_ppid && ! match_numlist (task.ppid, opt_ppid))
|
||||||
match = 0;
|
match = 0;
|
||||||
@ -553,11 +572,19 @@ select_procs (void)
|
|||||||
|
|
||||||
if (match ^ opt_negate) { /* Exclusive OR is neat */
|
if (match ^ opt_negate) { /* Exclusive OR is neat */
|
||||||
if (opt_newest) {
|
if (opt_newest) {
|
||||||
if (newest_start_time == task.start_time &&
|
if (saved_start_time == task.start_time &&
|
||||||
newest_pid > task.pid)
|
saved_pid > task.pid)
|
||||||
continue;
|
continue;
|
||||||
newest_start_time = task.start_time;
|
saved_start_time = task.start_time;
|
||||||
newest_pid = task.pid;
|
saved_pid = task.pid;
|
||||||
|
matches = 0;
|
||||||
|
}
|
||||||
|
if (opt_oldest) {
|
||||||
|
if (saved_start_time == task.start_time &&
|
||||||
|
saved_pid < task.pid)
|
||||||
|
continue;
|
||||||
|
saved_start_time = task.start_time;
|
||||||
|
saved_pid = task.pid;
|
||||||
matches = 0;
|
matches = 0;
|
||||||
}
|
}
|
||||||
if (opt_long) {
|
if (opt_long) {
|
||||||
|
Loading…
Reference in New Issue
Block a user