Filter top(1) display by COMMAND=abc OR COMMAND=xyz
Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
I'm experimenting with the top(1) program, and I'm trying to figure out how to display only specified program names. For example, if I invoke a command line like
$ ssh localhost sleep 15
I'd like to be able to filter top's display to show only processes whose program names are sshd
and sleep
.
When top is running, if I press 'O' (uppercase oh == case-sensitive filter) and add a filter COMMAND=sshd
, then I see what I expect: top displays only those processes whose program names start with sshd
. If I delete that filter (press '=') and create a new filter COMMAND=sleep
, I see the processes whose programs begin with sleep
.
However, if I create two filters where filter 1 is COMMAND=sshd
and filter 2 is COMMAND=sleep
, then top doesn't display anything at all, even when there are running sshd
and sleep
processes. So apparently this method of filter creation produces an AND
relationship: show if COMMAND=sshd
&& COMMAND=sleep
.
So how do I create a filter (or filter set) that produces the desired OR relationship: show if COMMAND=sshd
|| COMMAND=sleep
?
top filter
add a comment |Â
up vote
2
down vote
favorite
I'm experimenting with the top(1) program, and I'm trying to figure out how to display only specified program names. For example, if I invoke a command line like
$ ssh localhost sleep 15
I'd like to be able to filter top's display to show only processes whose program names are sshd
and sleep
.
When top is running, if I press 'O' (uppercase oh == case-sensitive filter) and add a filter COMMAND=sshd
, then I see what I expect: top displays only those processes whose program names start with sshd
. If I delete that filter (press '=') and create a new filter COMMAND=sleep
, I see the processes whose programs begin with sleep
.
However, if I create two filters where filter 1 is COMMAND=sshd
and filter 2 is COMMAND=sleep
, then top doesn't display anything at all, even when there are running sshd
and sleep
processes. So apparently this method of filter creation produces an AND
relationship: show if COMMAND=sshd
&& COMMAND=sleep
.
So how do I create a filter (or filter set) that produces the desired OR relationship: show if COMMAND=sshd
|| COMMAND=sleep
?
top filter
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I'm experimenting with the top(1) program, and I'm trying to figure out how to display only specified program names. For example, if I invoke a command line like
$ ssh localhost sleep 15
I'd like to be able to filter top's display to show only processes whose program names are sshd
and sleep
.
When top is running, if I press 'O' (uppercase oh == case-sensitive filter) and add a filter COMMAND=sshd
, then I see what I expect: top displays only those processes whose program names start with sshd
. If I delete that filter (press '=') and create a new filter COMMAND=sleep
, I see the processes whose programs begin with sleep
.
However, if I create two filters where filter 1 is COMMAND=sshd
and filter 2 is COMMAND=sleep
, then top doesn't display anything at all, even when there are running sshd
and sleep
processes. So apparently this method of filter creation produces an AND
relationship: show if COMMAND=sshd
&& COMMAND=sleep
.
So how do I create a filter (or filter set) that produces the desired OR relationship: show if COMMAND=sshd
|| COMMAND=sleep
?
top filter
I'm experimenting with the top(1) program, and I'm trying to figure out how to display only specified program names. For example, if I invoke a command line like
$ ssh localhost sleep 15
I'd like to be able to filter top's display to show only processes whose program names are sshd
and sleep
.
When top is running, if I press 'O' (uppercase oh == case-sensitive filter) and add a filter COMMAND=sshd
, then I see what I expect: top displays only those processes whose program names start with sshd
. If I delete that filter (press '=') and create a new filter COMMAND=sleep
, I see the processes whose programs begin with sleep
.
However, if I create two filters where filter 1 is COMMAND=sshd
and filter 2 is COMMAND=sleep
, then top doesn't display anything at all, even when there are running sshd
and sleep
processes. So apparently this method of filter creation produces an AND
relationship: show if COMMAND=sshd
&& COMMAND=sleep
.
So how do I create a filter (or filter set) that produces the desired OR relationship: show if COMMAND=sshd
|| COMMAND=sleep
?
top filter
top filter
asked Aug 17 at 4:51
Jim Fischer
30819
30819
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
0
down vote
With open source you can look at the code and see if it might be easy to do what you want. On my old rpm-based Fedora, I could easily download and unpack the source with
$ rpm -qf /usr/bin/top
procps-ng-3.3.10-11.fc24.x86_64
$ dnf download --source procps-ng
$ rpm -i procps-ng-3.3.10-11.fc24.src.rpm
$ rpmbuild -bp ~/rpmbuild/SPECS/procps-ng.spec --nodeps
$ cd ~/rpmbuild/BUILD/procps-ng-3.3.10/
and the code is in top/top.c
. Looking for the word filter eventually shows that function other_selection()
is implementing the o
or O
command with a small C struct in which sel = strcasestr
or sel = strstr
is being set for input such as COMMAND=somestring
. You can see the gitlab code for this release. It has changed since, but is similar.
A means to implement an or between 2 strings looked a little difficult, but a simple alternative seems to accept a regular expression instead of just doing a string comparison. You can then just change the assignment to sel = myfunction
and write a function that takes 2 strings and does a regexec()
instead of strstr()
.
If you prefer not to download and compile the program, you can write a small shim to load in front of the C library that overrides the strstr()
function with your own. However, I found this function was used in other places by top
, so I preferred to override strcasestr()
, which seems to be only used for the o
command. Create a file shim_strcasestr.c
with the following:
/* capture calls to a routine and replace with your code
* https://unix.stackexchange.com/a/463461/119298
* gcc -Wall -O2 -fpic -shared -ldl -o shim_strcasestr.so shim_strcasestr.c */
#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <regex.h>
#define NUMMATCH 1 /* max num matching capture groups in pattern */
char *strcasestr(const char *haystack, const char *needle)
static char *(*real_strcasestr)(const char *haystack, const char *needle) = NULL;
regex_t myexpn;
regmatch_t matches[NUMMATCH] = 0;
if (!real_strcasestr)
real_strcasestr = dlsym(RTLD_NEXT, "strcasestr");
char *error = dlerror();
if (error != NULL)
fprintf(stderr, "%sn", error);
exit(1);
if(needle[0]!='/') return real_strcasestr(haystack,needle);
int rc = regcomp(&myexpn, needle+1, REG_EXTENDED);
if(rc!=0)return NULL;
rc = regexec(&myexpn, haystack, NUMMATCH, matches, 0);
regfree(&myexpn);
if(rc==REG_NOMATCH)return NULL;
return (char*)haystack;
and compile it as shown in the comment. You can then run it as LD_PRELOAD=./shim_strcstr.so /usr/bin/top
and when you type the o
key, you can enter, for example, COMMAND=/sshd|sleep
and get the desired result. I added a check for an initial /
in the string so you can still get the original anycase matching if you omit it. Obviously, this code can be optimised to cache the regcomp()
result.
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
With open source you can look at the code and see if it might be easy to do what you want. On my old rpm-based Fedora, I could easily download and unpack the source with
$ rpm -qf /usr/bin/top
procps-ng-3.3.10-11.fc24.x86_64
$ dnf download --source procps-ng
$ rpm -i procps-ng-3.3.10-11.fc24.src.rpm
$ rpmbuild -bp ~/rpmbuild/SPECS/procps-ng.spec --nodeps
$ cd ~/rpmbuild/BUILD/procps-ng-3.3.10/
and the code is in top/top.c
. Looking for the word filter eventually shows that function other_selection()
is implementing the o
or O
command with a small C struct in which sel = strcasestr
or sel = strstr
is being set for input such as COMMAND=somestring
. You can see the gitlab code for this release. It has changed since, but is similar.
A means to implement an or between 2 strings looked a little difficult, but a simple alternative seems to accept a regular expression instead of just doing a string comparison. You can then just change the assignment to sel = myfunction
and write a function that takes 2 strings and does a regexec()
instead of strstr()
.
If you prefer not to download and compile the program, you can write a small shim to load in front of the C library that overrides the strstr()
function with your own. However, I found this function was used in other places by top
, so I preferred to override strcasestr()
, which seems to be only used for the o
command. Create a file shim_strcasestr.c
with the following:
/* capture calls to a routine and replace with your code
* https://unix.stackexchange.com/a/463461/119298
* gcc -Wall -O2 -fpic -shared -ldl -o shim_strcasestr.so shim_strcasestr.c */
#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <regex.h>
#define NUMMATCH 1 /* max num matching capture groups in pattern */
char *strcasestr(const char *haystack, const char *needle)
static char *(*real_strcasestr)(const char *haystack, const char *needle) = NULL;
regex_t myexpn;
regmatch_t matches[NUMMATCH] = 0;
if (!real_strcasestr)
real_strcasestr = dlsym(RTLD_NEXT, "strcasestr");
char *error = dlerror();
if (error != NULL)
fprintf(stderr, "%sn", error);
exit(1);
if(needle[0]!='/') return real_strcasestr(haystack,needle);
int rc = regcomp(&myexpn, needle+1, REG_EXTENDED);
if(rc!=0)return NULL;
rc = regexec(&myexpn, haystack, NUMMATCH, matches, 0);
regfree(&myexpn);
if(rc==REG_NOMATCH)return NULL;
return (char*)haystack;
and compile it as shown in the comment. You can then run it as LD_PRELOAD=./shim_strcstr.so /usr/bin/top
and when you type the o
key, you can enter, for example, COMMAND=/sshd|sleep
and get the desired result. I added a check for an initial /
in the string so you can still get the original anycase matching if you omit it. Obviously, this code can be optimised to cache the regcomp()
result.
add a comment |Â
up vote
0
down vote
With open source you can look at the code and see if it might be easy to do what you want. On my old rpm-based Fedora, I could easily download and unpack the source with
$ rpm -qf /usr/bin/top
procps-ng-3.3.10-11.fc24.x86_64
$ dnf download --source procps-ng
$ rpm -i procps-ng-3.3.10-11.fc24.src.rpm
$ rpmbuild -bp ~/rpmbuild/SPECS/procps-ng.spec --nodeps
$ cd ~/rpmbuild/BUILD/procps-ng-3.3.10/
and the code is in top/top.c
. Looking for the word filter eventually shows that function other_selection()
is implementing the o
or O
command with a small C struct in which sel = strcasestr
or sel = strstr
is being set for input such as COMMAND=somestring
. You can see the gitlab code for this release. It has changed since, but is similar.
A means to implement an or between 2 strings looked a little difficult, but a simple alternative seems to accept a regular expression instead of just doing a string comparison. You can then just change the assignment to sel = myfunction
and write a function that takes 2 strings and does a regexec()
instead of strstr()
.
If you prefer not to download and compile the program, you can write a small shim to load in front of the C library that overrides the strstr()
function with your own. However, I found this function was used in other places by top
, so I preferred to override strcasestr()
, which seems to be only used for the o
command. Create a file shim_strcasestr.c
with the following:
/* capture calls to a routine and replace with your code
* https://unix.stackexchange.com/a/463461/119298
* gcc -Wall -O2 -fpic -shared -ldl -o shim_strcasestr.so shim_strcasestr.c */
#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <regex.h>
#define NUMMATCH 1 /* max num matching capture groups in pattern */
char *strcasestr(const char *haystack, const char *needle)
static char *(*real_strcasestr)(const char *haystack, const char *needle) = NULL;
regex_t myexpn;
regmatch_t matches[NUMMATCH] = 0;
if (!real_strcasestr)
real_strcasestr = dlsym(RTLD_NEXT, "strcasestr");
char *error = dlerror();
if (error != NULL)
fprintf(stderr, "%sn", error);
exit(1);
if(needle[0]!='/') return real_strcasestr(haystack,needle);
int rc = regcomp(&myexpn, needle+1, REG_EXTENDED);
if(rc!=0)return NULL;
rc = regexec(&myexpn, haystack, NUMMATCH, matches, 0);
regfree(&myexpn);
if(rc==REG_NOMATCH)return NULL;
return (char*)haystack;
and compile it as shown in the comment. You can then run it as LD_PRELOAD=./shim_strcstr.so /usr/bin/top
and when you type the o
key, you can enter, for example, COMMAND=/sshd|sleep
and get the desired result. I added a check for an initial /
in the string so you can still get the original anycase matching if you omit it. Obviously, this code can be optimised to cache the regcomp()
result.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
With open source you can look at the code and see if it might be easy to do what you want. On my old rpm-based Fedora, I could easily download and unpack the source with
$ rpm -qf /usr/bin/top
procps-ng-3.3.10-11.fc24.x86_64
$ dnf download --source procps-ng
$ rpm -i procps-ng-3.3.10-11.fc24.src.rpm
$ rpmbuild -bp ~/rpmbuild/SPECS/procps-ng.spec --nodeps
$ cd ~/rpmbuild/BUILD/procps-ng-3.3.10/
and the code is in top/top.c
. Looking for the word filter eventually shows that function other_selection()
is implementing the o
or O
command with a small C struct in which sel = strcasestr
or sel = strstr
is being set for input such as COMMAND=somestring
. You can see the gitlab code for this release. It has changed since, but is similar.
A means to implement an or between 2 strings looked a little difficult, but a simple alternative seems to accept a regular expression instead of just doing a string comparison. You can then just change the assignment to sel = myfunction
and write a function that takes 2 strings and does a regexec()
instead of strstr()
.
If you prefer not to download and compile the program, you can write a small shim to load in front of the C library that overrides the strstr()
function with your own. However, I found this function was used in other places by top
, so I preferred to override strcasestr()
, which seems to be only used for the o
command. Create a file shim_strcasestr.c
with the following:
/* capture calls to a routine and replace with your code
* https://unix.stackexchange.com/a/463461/119298
* gcc -Wall -O2 -fpic -shared -ldl -o shim_strcasestr.so shim_strcasestr.c */
#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <regex.h>
#define NUMMATCH 1 /* max num matching capture groups in pattern */
char *strcasestr(const char *haystack, const char *needle)
static char *(*real_strcasestr)(const char *haystack, const char *needle) = NULL;
regex_t myexpn;
regmatch_t matches[NUMMATCH] = 0;
if (!real_strcasestr)
real_strcasestr = dlsym(RTLD_NEXT, "strcasestr");
char *error = dlerror();
if (error != NULL)
fprintf(stderr, "%sn", error);
exit(1);
if(needle[0]!='/') return real_strcasestr(haystack,needle);
int rc = regcomp(&myexpn, needle+1, REG_EXTENDED);
if(rc!=0)return NULL;
rc = regexec(&myexpn, haystack, NUMMATCH, matches, 0);
regfree(&myexpn);
if(rc==REG_NOMATCH)return NULL;
return (char*)haystack;
and compile it as shown in the comment. You can then run it as LD_PRELOAD=./shim_strcstr.so /usr/bin/top
and when you type the o
key, you can enter, for example, COMMAND=/sshd|sleep
and get the desired result. I added a check for an initial /
in the string so you can still get the original anycase matching if you omit it. Obviously, this code can be optimised to cache the regcomp()
result.
With open source you can look at the code and see if it might be easy to do what you want. On my old rpm-based Fedora, I could easily download and unpack the source with
$ rpm -qf /usr/bin/top
procps-ng-3.3.10-11.fc24.x86_64
$ dnf download --source procps-ng
$ rpm -i procps-ng-3.3.10-11.fc24.src.rpm
$ rpmbuild -bp ~/rpmbuild/SPECS/procps-ng.spec --nodeps
$ cd ~/rpmbuild/BUILD/procps-ng-3.3.10/
and the code is in top/top.c
. Looking for the word filter eventually shows that function other_selection()
is implementing the o
or O
command with a small C struct in which sel = strcasestr
or sel = strstr
is being set for input such as COMMAND=somestring
. You can see the gitlab code for this release. It has changed since, but is similar.
A means to implement an or between 2 strings looked a little difficult, but a simple alternative seems to accept a regular expression instead of just doing a string comparison. You can then just change the assignment to sel = myfunction
and write a function that takes 2 strings and does a regexec()
instead of strstr()
.
If you prefer not to download and compile the program, you can write a small shim to load in front of the C library that overrides the strstr()
function with your own. However, I found this function was used in other places by top
, so I preferred to override strcasestr()
, which seems to be only used for the o
command. Create a file shim_strcasestr.c
with the following:
/* capture calls to a routine and replace with your code
* https://unix.stackexchange.com/a/463461/119298
* gcc -Wall -O2 -fpic -shared -ldl -o shim_strcasestr.so shim_strcasestr.c */
#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <regex.h>
#define NUMMATCH 1 /* max num matching capture groups in pattern */
char *strcasestr(const char *haystack, const char *needle)
static char *(*real_strcasestr)(const char *haystack, const char *needle) = NULL;
regex_t myexpn;
regmatch_t matches[NUMMATCH] = 0;
if (!real_strcasestr)
real_strcasestr = dlsym(RTLD_NEXT, "strcasestr");
char *error = dlerror();
if (error != NULL)
fprintf(stderr, "%sn", error);
exit(1);
if(needle[0]!='/') return real_strcasestr(haystack,needle);
int rc = regcomp(&myexpn, needle+1, REG_EXTENDED);
if(rc!=0)return NULL;
rc = regexec(&myexpn, haystack, NUMMATCH, matches, 0);
regfree(&myexpn);
if(rc==REG_NOMATCH)return NULL;
return (char*)haystack;
and compile it as shown in the comment. You can then run it as LD_PRELOAD=./shim_strcstr.so /usr/bin/top
and when you type the o
key, you can enter, for example, COMMAND=/sshd|sleep
and get the desired result. I added a check for an initial /
in the string so you can still get the original anycase matching if you omit it. Obviously, this code can be optimised to cache the regcomp()
result.
answered Aug 19 at 9:31
meuh
30k11752
30k11752
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f463109%2ffilter-top1-display-by-command-abc-or-command-xyz%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password