Write a script that accepts group numbers (GIDs) as parameters












2















I'm trying to write a script that accepts group numbers (GID) as parameters. The parameters can be any number. The task of the script is to calculate and display the number of users belonging to the given groups (based on the /etc/passwd file). The script can not use the awk command.



I wrote it for now



#!/bin/bash 
cat /etc/passwd
test(){
local dir gid name pass shell uid user
while IFS=':' read user pass uid gid name dir shell ;do
}


and I do not know what's next?










share|improve this question




















  • 1





    Are you only interested in primary groups or should you also count users' supplementary groups?

    – Kusalananda
    Jan 7 at 20:47













  • Is this a homework exercise?

    – RalfFriedl
    Jan 7 at 21:00






  • 1





    @RalfFriedl I have yet to see a real question that is actually about parsing /etc/passwd for anything other than homework.

    – Kusalananda
    Jan 7 at 21:03
















2















I'm trying to write a script that accepts group numbers (GID) as parameters. The parameters can be any number. The task of the script is to calculate and display the number of users belonging to the given groups (based on the /etc/passwd file). The script can not use the awk command.



I wrote it for now



#!/bin/bash 
cat /etc/passwd
test(){
local dir gid name pass shell uid user
while IFS=':' read user pass uid gid name dir shell ;do
}


and I do not know what's next?










share|improve this question




















  • 1





    Are you only interested in primary groups or should you also count users' supplementary groups?

    – Kusalananda
    Jan 7 at 20:47













  • Is this a homework exercise?

    – RalfFriedl
    Jan 7 at 21:00






  • 1





    @RalfFriedl I have yet to see a real question that is actually about parsing /etc/passwd for anything other than homework.

    – Kusalananda
    Jan 7 at 21:03














2












2








2








I'm trying to write a script that accepts group numbers (GID) as parameters. The parameters can be any number. The task of the script is to calculate and display the number of users belonging to the given groups (based on the /etc/passwd file). The script can not use the awk command.



I wrote it for now



#!/bin/bash 
cat /etc/passwd
test(){
local dir gid name pass shell uid user
while IFS=':' read user pass uid gid name dir shell ;do
}


and I do not know what's next?










share|improve this question
















I'm trying to write a script that accepts group numbers (GID) as parameters. The parameters can be any number. The task of the script is to calculate and display the number of users belonging to the given groups (based on the /etc/passwd file). The script can not use the awk command.



I wrote it for now



#!/bin/bash 
cat /etc/passwd
test(){
local dir gid name pass shell uid user
while IFS=':' read user pass uid gid name dir shell ;do
}


and I do not know what's next?







linux bash gid






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 7 at 20:59









RalfFriedl

5,3353925




5,3353925










asked Jan 7 at 20:36









Johny NJohny N

111




111








  • 1





    Are you only interested in primary groups or should you also count users' supplementary groups?

    – Kusalananda
    Jan 7 at 20:47













  • Is this a homework exercise?

    – RalfFriedl
    Jan 7 at 21:00






  • 1





    @RalfFriedl I have yet to see a real question that is actually about parsing /etc/passwd for anything other than homework.

    – Kusalananda
    Jan 7 at 21:03














  • 1





    Are you only interested in primary groups or should you also count users' supplementary groups?

    – Kusalananda
    Jan 7 at 20:47













  • Is this a homework exercise?

    – RalfFriedl
    Jan 7 at 21:00






  • 1





    @RalfFriedl I have yet to see a real question that is actually about parsing /etc/passwd for anything other than homework.

    – Kusalananda
    Jan 7 at 21:03








1




1





Are you only interested in primary groups or should you also count users' supplementary groups?

– Kusalananda
Jan 7 at 20:47







Are you only interested in primary groups or should you also count users' supplementary groups?

– Kusalananda
Jan 7 at 20:47















Is this a homework exercise?

– RalfFriedl
Jan 7 at 21:00





Is this a homework exercise?

– RalfFriedl
Jan 7 at 21:00




1




1





@RalfFriedl I have yet to see a real question that is actually about parsing /etc/passwd for anything other than homework.

– Kusalananda
Jan 7 at 21:03





@RalfFriedl I have yet to see a real question that is actually about parsing /etc/passwd for anything other than homework.

– Kusalananda
Jan 7 at 21:03










1 Answer
1






active

oldest

votes


















2














All groups are in the group database. To count the number of members of a group, extract the members and count the commas in-between them. The number of group members is 1 plus this number.



#!/bin/sh

n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

printf 'There are %d members of group %sn' "$(( n + 1 ))" "$1"


The downside of this approach is that you will always get at least 1 member as output, even if the group is invalid. We can test for a valid group first though:



#!/bin/sh

if ! getent group "$1" >/dev/null; then
printf 'No such group: %sn' "$1" >&2
exit 1
fi

n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

printf 'There are %d members of group %sn' "$(( n + 1 ))" "$1"


The script accept both numeric GIDs and group names as its first command line argument.



With awk, you would instead do



n=$( getent group "$1" | awk -F : '{ print split($4,dummy,",") }' )


and then not add 1 to $n later, or just



getent group "$1" | awk -F : '
{
printf("There are %d members of group %s (%d)n",
split($4,dummy,","), $1, $3)
}'


without the (shell) printf or the n variable.



This counts group memberships as recorded in the group database. To count only primary group memberships, use something like



n=$( getent passwd | cut -d : -f 4 | grep -cxF "$1" )


But again, you may want to check that $1 is indeed a valid group ID first.



To count both primary and supplementary group memberships, it may be best to loop over all users and use id on each:



getent passwd | cut -d : -f 1 |
while read user; do
if id -G "$user" | tr ' ' 'n' | grep -q -xF "$1"; then
n=$(( n + 1 ))
fi
done


This would extract all usernames, then call id -G on each and transform the resulting list of GIDs into a newline-delimited list. The grep then determines whether the given GID is part of that list, and if it is, n is incremented by one.



Or quicker, but uglier,



n=$( getent passwd | cut -d : -f 1 |
while read user; do
id -G "$user"
done | tr ' ' 'n' | grep -c -xF "$1" )


or even,



n=$( getent passwd    | cut -d : -f 1 |
xargs -n 1 id -G | tr ' ' 'n' |
grep -c -xF "$1" )


The reason this may be a good approach is that there may be users whose primary group does not contain themselves in the group database.






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',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    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%2f493088%2fwrite-a-script-that-accepts-group-numbers-gids-as-parameters%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    All groups are in the group database. To count the number of members of a group, extract the members and count the commas in-between them. The number of group members is 1 plus this number.



    #!/bin/sh

    n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

    printf 'There are %d members of group %sn' "$(( n + 1 ))" "$1"


    The downside of this approach is that you will always get at least 1 member as output, even if the group is invalid. We can test for a valid group first though:



    #!/bin/sh

    if ! getent group "$1" >/dev/null; then
    printf 'No such group: %sn' "$1" >&2
    exit 1
    fi

    n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

    printf 'There are %d members of group %sn' "$(( n + 1 ))" "$1"


    The script accept both numeric GIDs and group names as its first command line argument.



    With awk, you would instead do



    n=$( getent group "$1" | awk -F : '{ print split($4,dummy,",") }' )


    and then not add 1 to $n later, or just



    getent group "$1" | awk -F : '
    {
    printf("There are %d members of group %s (%d)n",
    split($4,dummy,","), $1, $3)
    }'


    without the (shell) printf or the n variable.



    This counts group memberships as recorded in the group database. To count only primary group memberships, use something like



    n=$( getent passwd | cut -d : -f 4 | grep -cxF "$1" )


    But again, you may want to check that $1 is indeed a valid group ID first.



    To count both primary and supplementary group memberships, it may be best to loop over all users and use id on each:



    getent passwd | cut -d : -f 1 |
    while read user; do
    if id -G "$user" | tr ' ' 'n' | grep -q -xF "$1"; then
    n=$(( n + 1 ))
    fi
    done


    This would extract all usernames, then call id -G on each and transform the resulting list of GIDs into a newline-delimited list. The grep then determines whether the given GID is part of that list, and if it is, n is incremented by one.



    Or quicker, but uglier,



    n=$( getent passwd | cut -d : -f 1 |
    while read user; do
    id -G "$user"
    done | tr ' ' 'n' | grep -c -xF "$1" )


    or even,



    n=$( getent passwd    | cut -d : -f 1 |
    xargs -n 1 id -G | tr ' ' 'n' |
    grep -c -xF "$1" )


    The reason this may be a good approach is that there may be users whose primary group does not contain themselves in the group database.






    share|improve this answer






























      2














      All groups are in the group database. To count the number of members of a group, extract the members and count the commas in-between them. The number of group members is 1 plus this number.



      #!/bin/sh

      n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

      printf 'There are %d members of group %sn' "$(( n + 1 ))" "$1"


      The downside of this approach is that you will always get at least 1 member as output, even if the group is invalid. We can test for a valid group first though:



      #!/bin/sh

      if ! getent group "$1" >/dev/null; then
      printf 'No such group: %sn' "$1" >&2
      exit 1
      fi

      n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

      printf 'There are %d members of group %sn' "$(( n + 1 ))" "$1"


      The script accept both numeric GIDs and group names as its first command line argument.



      With awk, you would instead do



      n=$( getent group "$1" | awk -F : '{ print split($4,dummy,",") }' )


      and then not add 1 to $n later, or just



      getent group "$1" | awk -F : '
      {
      printf("There are %d members of group %s (%d)n",
      split($4,dummy,","), $1, $3)
      }'


      without the (shell) printf or the n variable.



      This counts group memberships as recorded in the group database. To count only primary group memberships, use something like



      n=$( getent passwd | cut -d : -f 4 | grep -cxF "$1" )


      But again, you may want to check that $1 is indeed a valid group ID first.



      To count both primary and supplementary group memberships, it may be best to loop over all users and use id on each:



      getent passwd | cut -d : -f 1 |
      while read user; do
      if id -G "$user" | tr ' ' 'n' | grep -q -xF "$1"; then
      n=$(( n + 1 ))
      fi
      done


      This would extract all usernames, then call id -G on each and transform the resulting list of GIDs into a newline-delimited list. The grep then determines whether the given GID is part of that list, and if it is, n is incremented by one.



      Or quicker, but uglier,



      n=$( getent passwd | cut -d : -f 1 |
      while read user; do
      id -G "$user"
      done | tr ' ' 'n' | grep -c -xF "$1" )


      or even,



      n=$( getent passwd    | cut -d : -f 1 |
      xargs -n 1 id -G | tr ' ' 'n' |
      grep -c -xF "$1" )


      The reason this may be a good approach is that there may be users whose primary group does not contain themselves in the group database.






      share|improve this answer




























        2












        2








        2







        All groups are in the group database. To count the number of members of a group, extract the members and count the commas in-between them. The number of group members is 1 plus this number.



        #!/bin/sh

        n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

        printf 'There are %d members of group %sn' "$(( n + 1 ))" "$1"


        The downside of this approach is that you will always get at least 1 member as output, even if the group is invalid. We can test for a valid group first though:



        #!/bin/sh

        if ! getent group "$1" >/dev/null; then
        printf 'No such group: %sn' "$1" >&2
        exit 1
        fi

        n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

        printf 'There are %d members of group %sn' "$(( n + 1 ))" "$1"


        The script accept both numeric GIDs and group names as its first command line argument.



        With awk, you would instead do



        n=$( getent group "$1" | awk -F : '{ print split($4,dummy,",") }' )


        and then not add 1 to $n later, or just



        getent group "$1" | awk -F : '
        {
        printf("There are %d members of group %s (%d)n",
        split($4,dummy,","), $1, $3)
        }'


        without the (shell) printf or the n variable.



        This counts group memberships as recorded in the group database. To count only primary group memberships, use something like



        n=$( getent passwd | cut -d : -f 4 | grep -cxF "$1" )


        But again, you may want to check that $1 is indeed a valid group ID first.



        To count both primary and supplementary group memberships, it may be best to loop over all users and use id on each:



        getent passwd | cut -d : -f 1 |
        while read user; do
        if id -G "$user" | tr ' ' 'n' | grep -q -xF "$1"; then
        n=$(( n + 1 ))
        fi
        done


        This would extract all usernames, then call id -G on each and transform the resulting list of GIDs into a newline-delimited list. The grep then determines whether the given GID is part of that list, and if it is, n is incremented by one.



        Or quicker, but uglier,



        n=$( getent passwd | cut -d : -f 1 |
        while read user; do
        id -G "$user"
        done | tr ' ' 'n' | grep -c -xF "$1" )


        or even,



        n=$( getent passwd    | cut -d : -f 1 |
        xargs -n 1 id -G | tr ' ' 'n' |
        grep -c -xF "$1" )


        The reason this may be a good approach is that there may be users whose primary group does not contain themselves in the group database.






        share|improve this answer















        All groups are in the group database. To count the number of members of a group, extract the members and count the commas in-between them. The number of group members is 1 plus this number.



        #!/bin/sh

        n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

        printf 'There are %d members of group %sn' "$(( n + 1 ))" "$1"


        The downside of this approach is that you will always get at least 1 member as output, even if the group is invalid. We can test for a valid group first though:



        #!/bin/sh

        if ! getent group "$1" >/dev/null; then
        printf 'No such group: %sn' "$1" >&2
        exit 1
        fi

        n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

        printf 'There are %d members of group %sn' "$(( n + 1 ))" "$1"


        The script accept both numeric GIDs and group names as its first command line argument.



        With awk, you would instead do



        n=$( getent group "$1" | awk -F : '{ print split($4,dummy,",") }' )


        and then not add 1 to $n later, or just



        getent group "$1" | awk -F : '
        {
        printf("There are %d members of group %s (%d)n",
        split($4,dummy,","), $1, $3)
        }'


        without the (shell) printf or the n variable.



        This counts group memberships as recorded in the group database. To count only primary group memberships, use something like



        n=$( getent passwd | cut -d : -f 4 | grep -cxF "$1" )


        But again, you may want to check that $1 is indeed a valid group ID first.



        To count both primary and supplementary group memberships, it may be best to loop over all users and use id on each:



        getent passwd | cut -d : -f 1 |
        while read user; do
        if id -G "$user" | tr ' ' 'n' | grep -q -xF "$1"; then
        n=$(( n + 1 ))
        fi
        done


        This would extract all usernames, then call id -G on each and transform the resulting list of GIDs into a newline-delimited list. The grep then determines whether the given GID is part of that list, and if it is, n is incremented by one.



        Or quicker, but uglier,



        n=$( getent passwd | cut -d : -f 1 |
        while read user; do
        id -G "$user"
        done | tr ' ' 'n' | grep -c -xF "$1" )


        or even,



        n=$( getent passwd    | cut -d : -f 1 |
        xargs -n 1 id -G | tr ' ' 'n' |
        grep -c -xF "$1" )


        The reason this may be a good approach is that there may be users whose primary group does not contain themselves in the group database.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 7 at 22:59

























        answered Jan 7 at 20:58









        KusalanandaKusalananda

        124k16234386




        124k16234386






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Unix & Linux Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f493088%2fwrite-a-script-that-accepts-group-numbers-gids-as-parameters%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Morgemoulin

            Scott Moir

            Souastre