GNU Info

Info Node: (gawk.info)Id Program

(gawk.info)Id Program


Next: Split Program Prev: Egrep Program Up: Clones
Enter node , (file) or (file)node

Printing out User Information
-----------------------------

   The `id' utility lists a user's real and effective user-id numbers,
real and effective group-id numbers, and the user's group set, if any.
`id' only prints the effective user-id and group-id if they are
different from the real ones.  If possible, `id' also supplies the
corresponding user and group names.  The output might look like this:

     $ id
     -| uid=2076(arnold) gid=10(staff) groups=10(staff),4(tty)

   This information is part of what is provided by `gawk''s `PROCINFO'
array (Note: Built-in Variables).  However, the `id' utility provides
a more palatable output than just individual numbers.

   Here is a simple version of `id' written in `awk'.  It uses the user
database library functions (Note: Reading the User Database.
)  and the group database library functions (Note: Reading
the Group Database.):

   The program is fairly straightforward.  All the work is done in the
`BEGIN' rule.  The user and group ID numbers are obtained from
`PROCINFO'.  The code is repetitive.  The entry in the user database
for the real user-id number is split into parts at the `:'. The name is
the first field.  Similar code is used for the effective user-id number
and the group numbers.

     # id.awk --- implement id in awk
     #
     # Requires user and group library functions
     # output is:
     # uid=12(foo) euid=34(bar) gid=3(baz) \
     #             egid=5(blat) groups=9(nine),2(two),1(one)
     
     BEGIN    \
     {
         uid = PROCINFO["uid"]
         euid = PROCINFO["euid"]
         gid = PROCINFO["gid"]
         egid = PROCINFO["egid"]
     
         printf("uid=%d", uid)
         pw = getpwuid(uid)
         if (pw != "") {
             split(pw, a, ":")
             printf("(%s)", a[1])
         }
     
         if (euid != uid) {
             printf(" euid=%d", euid)
             pw = getpwuid(euid)
             if (pw != "") {
                 split(pw, a, ":")
                 printf("(%s)", a[1])
             }
         }
     
         printf(" gid=%d", gid)
         pw = getgrgid(gid)
         if (pw != "") {
             split(pw, a, ":")
             printf("(%s)", a[1])
         }
     
         if (egid != gid) {
             printf(" egid=%d", egid)
             pw = getgrgid(egid)
             if (pw != "") {
                 split(pw, a, ":")
                 printf("(%s)", a[1])
             }
         }
     
         for (i = 1; ("group" i) in PROCINFO; i++) {
             if (i == 1)
                 printf(" groups=")
             group = PROCINFO["group" i]
             printf("%d", group)
             pw = getgrgid(group)
             if (pw != "") {
                 split(pw, a, ":")
                 printf("(%s)", a[1])
             }
             if (("group" (i+1)) in PROCINFO)
                 printf(",")
         }
     
         print ""
     }

   The test in the `for' loop is worth noting.  Any supplementary
groups in the `PROCINFO' array have the indices `"group1"' through
`"groupN"' for some N; i.e., the total number of supplementary groups.
The problem is, we don't know in advance how many of these groups there
are.

   This loop works by starting at one, concatenating the value with
`"group"', and then using `in' to see if that value is in the array.
Eventually, `i' is incremented past the last group in the array and the
loop exits.

   The loop is also correct if there are _no_ supplementary groups;
then the condition is false the first time it's tested, and the loop
body never executes.


automatically generated by info2www version 1.2.2.9