[SOLVED] Is getent a better option than parsing the /etc/passwd file through while loop
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Now, you iterate over all entries in /etc/passwd. I'd do it with
Code:
( while read; do
USID="$(echo "$REPLY" | cut -d: -f3)"
[..]
done ) < /etc/passwd
For me this code looks pretty ineffecient as you have to traverse through all the entries of /etc/passwd in while loop.
But In my above pasted code I will get all usernames at once through awk -F: '{printf " "$1}' /etc/passwd
And I use getent to find the details of user which internally finds it through administrative databases like passwd and shadow. Instead of passing /etc/passwd through while loop.
Distribution: approximately NixOS (http://nixos.org)
Posts: 1,900
Rep:
In the beginning I would recommend also getting "groups" entry into a variable, and parse the line taken from variable then.
Let us now try to compare what actually happens.
I suggest reading each passwd line once, and parse it in memory. You say that retrieving one field a time is better. Unfortunately, what actually happens is that the first awk invocation will read entire /etc/passwd file. Also, getent will read entire /etc/passwd pefix until the needed line - and you retrieve the same line multiple times. Also your code spawns more processes.
By the way, on my machine the only reasonable way to get user's primary group is using passwd entry and then getting an entry from /etc/group file (here getent will fit nice). "groups" just prints all groups the user is in without obvious emphasis for primary group.
Distribution: approximately NixOS (http://nixos.org)
Posts: 1,900
Rep:
Well, I don't use awk much (and so I have never seen system() function).. Actually, is it just so time-critical code to optimize it beyond removing obvious problems?
Well, I don't use awk much (and so I have never seen system() function).. Actually, is it just so time-critical code to optimize it beyond removing obvious problems?
Yes, We need to reduce the time of execution as much as possible.
Distribution: approximately NixOS (http://nixos.org)
Posts: 1,900
Rep:
I guess spawning a couple of processes per line is not too fast, too. I guess writing it all in a compiled language is what you need if it is really time-critical. Also, you'd better parse the files linearly on load (you need all entries anyway) and put results in a data structure more suitable for search than a linear list.
Yes I can see how that is a little confusing, so here we go:
sec variable - this is to store the secondary groups that a user "may" be a part of, remembering that you do not have to have more than your primary group.
so to explain:
Quote:
if(sec ~ /./)
This is simply a test to see if sec has anything stored in it, ie at least one character ... hence the .
grps variable - the variable stores each line one at a time from the file /etc/group (this part is easy)
so to explain:
Quote:
if(grps ~ "."$1)
Here $1 is the name of the user from the file /etc/passwd so to test if a user is part of any other group the name must appear on the line but not at the start of the line, therefore there should be at least one character (actually many but testing for one is sufficient) prior to the users name.
As an example, my username is grail so the following line shows me as a member of the following group:
Code:
dialout:x:20:grail
So our test would now see that there is a ":" prior to name grail so this is a secondary group.
However the following group is not secondary:
Code:
grail:x:1000:
As there are no characters prior to name it is not a secondary group
As of typing this I have realised the logic is slightly floored because if you put all users into the primary group of 'users' this will show them as both a primary and secondary of the group 'users' ...
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.