Filter top(1) display by COMMAND=abc OR COMMAND=xyz

Multi tool use
Multi tool use

The name of the pictureThe name of the pictureThe name of the pictureClash 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?










share|improve this question

























    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?










    share|improve this question























      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?










      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Aug 17 at 4:51









      Jim Fischer

      30819




      30819




















          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.






          share|improve this answer




















            Your Answer







            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "106"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            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






























            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.






            share|improve this answer
























              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.






              share|improve this answer






















                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.






                share|improve this answer












                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.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Aug 19 at 9:31









                meuh

                30k11752




                30k11752



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    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













































































                    CD71Rs3F,dSrL yDQhnQx0PfjxBUeCfx44Se pP8XP5,nOg5Iz0ChJSeeRzy6WG,qne2g1N 596d7mWJ7Jz,8I
                    9Ks 1oU rZ s2IuQJi2xt7,JC UGkt,m,N9If3eZCF N39FHYkKfRRT52Y3n8dsp h,4u5oue0AW2Odujz,PHmB6YVkAkMTN7QWTOPvblrD

                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    How many registers does an x86_64 CPU actually have?

                    Displaying single band from multi-band raster using QGIS