A (surprising) missing Unix tool program

June 13, 2010

Every so often, I run across surprising omissions in the Unix toolchest of small utilities and the like. Today's is a program to print some or all of the various passwd fields for a user, by extended analogy to id (which will print user and group information in useful ways); you would use it to extract data like the shell or the home directory for a particular account.

(Perhaps I should instead call this a lack in the 'GNU Unix toolchest', since everyone else seems to have more or less frozen their idea of what 'Unix' and its toolchest is and so would probably argue that the Unix toolchest has exactly what it's supposed to have and is not missing anything. I disagree.)

The traditional answer to this is to use awk or cut on /etc/passwd to extract what you want. The problem with this is that it has been a very long time indeed since /etc/passwd was sure to have information for all logins on the system. If you are using YP/NIS, LDAP, or any number of other sources of account information, what you want is simply not there in /etc/passwd. On a modern Unix machine, you thus really do want and need something that calls getpwnam() and reports back the requested bits.

(In the process I think it should regularize the information a bit; the classic case would be to report a blank shell field as a shell of /bin/sh. This saves other programs from having to deal with both cases and getting it wrong sooner or later.)

I know that I could easily write this in Perl or Python (and with slightly more work and masochism, in C). That's not the point; I don't just want a program to do this, I want a utility that's generally present on machines (and that will not be yet another local piece of magic for my coworkers to learn). In the absence of such a tool, I just use awk and cut, since that's the 'standard' answer and it still works on our machines.

Comments on this page:

From at 2010-06-13 03:28:04:

You seem to be describing getent.

From at 2010-06-13 05:11:14:

Also, GNU is Not Unix.

By cks at 2010-06-13 09:47:43:

Ah, interesting. Getent is only half of what I want, but it does deal with the core problem that I raised. I'll have to remember it for future use, since it's more convenient (and easier to get right) than grep.

From at 2010-06-13 18:45:40:

I wouldn't use grep, or even getent. To get the shell for the user "james" I'd probably do something like:

python -c 'import pwd; print pwd.getpwnam("james").pw_shell'

...it's a "little heavy", but it's going to be correct much more often and with much less work.

By cks at 2010-06-14 11:25:56:

The problem with the quick Python version is that most of the interesting cases have a non-constant username. In turn this requires error checking to make sure that the username exists; otherwise you get nice Python stack backtraces, which is not what I want from my scripts. And that makes the quick Python version less and less quick.

Written on 13 June 2010.
« iSCSI Enterprise Target and disk write caches (and ZFS)
A thought on feed readers versus the social web »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Jun 13 00:54:24 2010
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.