2

On RHEL, there is a command lid, which lists group users, no matter primary group or secondary group.

[root@192 ~]# id user1
uid=1000(user1) gid=1000(user1) groups=1000(user1),1001(g1)
[root@192 ~]# id user2
uid=1001(user2) gid=1002(user2) groups=1002(user2),1001(g1)
[root@192 ~]# id user3
uid=1002(user3) gid=1001(g1) groups=1001(g1)
[root@192 ~]# lid -g g1
 user3(uid=1002)
 user1(uid=1000)
 user2(uid=1001)
[root@192 ~]#

But it doesn't exist on Ubuntu. Is there a similar one?

  • FYI, there's also members from the members package. The output format is very different from lid (it just prints all member usernames on one line separated by spaces, without uid= details) but, by default, it also lists both primary and secondary members of a group. The default is -a or --all to show all members on one line, and various options cause it print only primary (-p, --primary), only secondary (-s, --secondary), or primary and secondary members on separate lines (-t or --two-lines). – cas Jun 05 '22 at 06:30
  • 3
  • https://unix.stackexchange.com/a/241219/70524 covers lid/libuser-lid, and the other answers cover other tools – muru Jun 05 '22 at 09:03

2 Answers2

6

It does exist in Ubuntu, but it’s provided under a different name:

sudo libuser-lid -g g1

It’s part of the libuser package, install that if necessary:

sudo apt install libuser

The reason it’s not named lid is that lid is provided in the id-utils package and has a different purpose.

Stephen Kitt
  • 434,908
1

The described functionality can be achieved using standard utilities:

for u in $(getent group | grep '^g1:' | cut -d: -f4 | tr , '\n'); do
    printf "%s(uid=%d)\n" $u $(id -u "$u")
done

Update: the command:

getent passwd | grep -E '^([^:]+:){3}'$(getent group | grep '^g1:' | cut -d: -f3)':' | cut -d: -f1

will retrieve lines from /etc/passwd corresponding to users whose primary group is g1. This can be combined with the previous command:

for u in $({ getent passwd | grep -E '^([^:]+:){3}'$(getent group | \
        grep '^g1:' | cut -d: -f3)':' | cut -d: -f1; \
    getent group | grep '^g1:' | cut -d: -f4 | tr , '\n'; }); do
    printf "%s(uid=%d)\n" $u $(id -u "$u")
done | sort | uniq

with the added sorting and removal of duplicates at the end.

This command can be made into a shell function for convenience, using the group name as a parameter:

lid_replacement()
{
    for u in $({ getent passwd | grep -E '^([^:]+:){3}'$(getent group | \
            grep '^'$1':' | cut -d: -f3)':' | cut -d: -f1; \
        getent group | grep '^'$1':' | cut -d: -f4 | tr , '\n'; }); do
        printf "%s(uid=%d)\n" $u $(id -u "$u")
    done | sort | uniq
}

call as: lid_replacement g1

Edit: Updated regex to match the exact group name.

Edit 2: Updated to use getent(1) and added the function lid_replacement.

Vilinkameni
  • 781
  • 1
  • 4
  • 12
  • About the second point, that can be easily solved by changing the regex. About the third point, I'm not aware of what that "something" would be. /etc/group is a standard location in Unix-like systems to store group information. – Vilinkameni Jun 04 '22 at 11:53
  • About that first point, I wasn't familiar with the nsswitch mechanism nor LDAP, NIS etc. From what I could read in man 1 getent and man 5 nsswitch.conf it seems as if the nsswitch mechanism is using various sources to read the user/group information, with the ability to present it in the format of /etc/passwd or /etc/group. So, the easy fix would be to query the output of getent passwd or getent group instead ot the corresponding files. – Vilinkameni Jun 05 '22 at 08:06
  • s/first/third/ in my previous comment. I addressed the first point earlier in an update to my answer. – Vilinkameni Jun 05 '22 at 08:20