plan 9 who is a 3 line shell script that just greps the output of ps and sorts it. You could eliminate ps and just grep through /proc but why reinvent the wheel when an existing tool already does part of the job?
I see some comments here citing a lack of options, most of which appear to have nothing to do with who is logged into the machine.
* /proc is as portable as ps, but that doesn't really amount to much because neither is really portable at all. Pretty much every operating system's /proc is different; and no implementation of the ps command fully conforms to even the limited subset laid out in the Single Unix Specification.
this version appears to derive from rewriting unix who in the 4.4BSD era to replace AT&T code (copyright 1989 / no AT&T in header notes as basis for assumption)
> Of course, this only mocks the most basic features of the who command and doesn’t handle any option, like the famous `who am i` or `who mom hates`.
it's not quite an apples to apples comparison as his rewrite doesn't handle any options or cleverness, but it's still a massive jump in LOC.
Wow, I touched a nerve I don't understand, to get a -1, so I'll explain myself. The GNU code looks like it's portable to a bunch of OSes, some with and some without a given feature. That sort of portability leads to having a lot of #ifdefs. If you're only going to support a handful of OSes - because that's all most people care about - then of course your code is going to be smaller.
As a concrete example, the linked-to "who" uses:
if (entry.ut_type != USER_PROCESS)
continue;
The GNU one uses:
if (IS_USER_PROCESS (utmp_buf))
The IS_USER_PROCESS() macro is in gnulib's readutmp.h (which would need to be included in the overall line cound):
The UT_USER maps to ut_user on some systems, and ut_name on others:
/* Accessor macro for the member named ut_user or ut_name. */
# if HAVE_UTMPX_H
# if HAVE_STRUCT_UTMPX_UT_USER
# define UT_USER(Utmp) ((Utmp)->ut_user)
# endif
# if HAVE_STRUCT_UTMPX_UT_NAME
# undef UT_USER
# define UT_USER(Utmp) ((Utmp)->ut_name)
# endif
Each of those other macros supports cases where the machine supports a given test, and when it doesn't. Including for machines which don't implement ut_type! (That's what the UT_TYPE_NOT_DEFINED case is for, which falls back to using the time field ... which has its own set of variants!)
Portability is neither options nor cleverness, so I added it to the list of considerations. But then again, most people now don't need to support decades of history and scores of Unix variants.
I see some comments here citing a lack of options, most of which appear to have nothing to do with who is logged into the machine.