tags:

views:

130

answers:

3

I'm looking for a way of mapping a uid (unique number representing a system user) to a user name using Perl.

Please don't suggest greping /etc/passwd :)

Edit

As a clarification, I wasn't looking for a solution that involved reading /etc/passwd explicitly. I realize that under the hood any solution would end up doing this, but I was searching for a library function to do it for me.

+1  A: 

Read /etc/passwd and hash the UID to login name.

Edit:

$uid   = getpwnam($name);
$name  = getpwuid($num);
$name  = getpwent();
$gid   = getgrnam($name);
$name  = getgrgid($num;
$name  = getgrent();

As you can see, regardless of which one you pick, the system call reads from /etc/passwd (see this for reference)

Arrieta
Don't down vote. Regardless of what you do, eventually you (or a system call) will read and hash from /etc/passwd.
Arrieta
And regardless of what file you grep, the CPU will eventually execute assembly commands, so why just not code everything in assembler? So you `grep` files in your own way, and then you wonder, [How did Perl gain a reputation for being a write-only language?](http://stackoverflow.com/questions/2702728/how-did-perl-gain-a-reputation-for-being-a-write-only-language)
Pavel Shved
Yes down vote: Reading the file directly should *never* be the first tool in one's box. A good answer would have presented the built-ins as the default option and alluded to reading `/etc/passwd` as a possible optimization.Also: Telling people how to vote? Laughable.
darch
A: 

Actually I would suggest building a hash based on /etc/passwd :-) This should work well as the user ids are required to be unique.

nc3b
Any constructive feedback ? How else can you get information about users / user ids ?
nc3b
Because I'm looking for a perl library that will do this for me. I understand that at some point it involves reading from /etc/password.
Mike
I fail to see where in your question you suggested this :-) I also don't quite get the benefits of a "library" to do this. It's a *file* man, do you need libraries to read colon separated values ?
nc3b
i thought it was suggested with my cute remark near the end. although i guess i should have been more clear.
Mike
and, yes having a library is always more valuable, even if the task is trivial.
Mike
Also, the library calls may be implemented to use other databases like YP/NIS/NIS+/LDAP/etc. in addition or in the place of `/etc/passwd`. Not all systems are standalone.
Chris Johnsen
@Chris Johnsen This is indeed a good argument, thank you :-)
nc3b
+7  A: 

The standard function getpwuid, just like the same C function, gets user information based on its ID. No uses needed:

my ($name) = getpwuid(1000);
print $name,"\n";

Although it eventually reads /etc/passwd file, using standard interfaces is much more clear for other users to see, let alone it saves you some keystrokes.

Pavel Shved
Ok, out of curiosity I made a small script. I call `getpwuid(1000);` **5 times** in a row. *Literally* in a row. Then I `strace` and grep the output. What is this ? Could it be that it calls "`open`" **5 times** ? Yes! And that is for the same user. Now I see, 4 I/O calls extra are TOTALLY worth the extra keystrokes.
nc3b
@nc3b If I was interested in performance I would be doing this in C. I'm optimizing for development time instead of resource usage. (nb, Perl is the best language for this in my current environment)
Mike
@Mike You know best what your priorities are. In my opinion cutting on I/O access is not optimization, it's basic. I mean, run `getpwuid(1000)` in a loop and you'll see good old linear running time. Anyway, I am just glad I did this test, I learned something today :-)
nc3b
`getpwuid` cannot assume that the `/etc/passwd` file has not changed since the last call, however unlikely that may be.
mobrule
mobrule is right. `/etc/passwd` can change at any time. If you're worried about performance for user lookups, just memoize the results of `getpwuid` (and be prepared to accept the consequences!)
friedo
you can always use the timestamp of /etc/passwd as basis for assuming your cache is outdated
Mike