Getting groups you belong to in perl

Linda Walsh
Fri Mar 21 11:13:00 GMT 2014

Andrey Repin wrote:
> Greetings, Corinna Vinschen!
>>>>>> Don't know if this list is more appropriate than the Perl one but my
>>>>>> question is actually about porting a Perl script to Cygwin. I need to
>>>>>> check if the current user running the script belongs to a pre-defined group.
FWIW, I run a bash script at logon to populate a bash array
called $_GROUPS_.  I mention it, because you could do similarly
in perl if other methods don't work.

> echo ${_GROUPS_[@]}
1053 517 512 545 11612288 518 519 513 544 520 201 260
echo -E ${!_GROUPS_[@]}
Bliss\Trusted Local Net Users Bliss\Cert Publishers Bliss\Domain Admins Users 
High Mandatory Level Bliss\Schema Admins Bliss\Enterprise Admins None 
Administrators Bliss\Group Policy Creator Owners lawgroup
It uses the cygwin 'id' program.

The array in the env is a convenience -- not a secure list.
Better to parse the output of id.

My bash routine is called via my 'bash_env' because bash currently
does not propagate arrays -- so the array is stored in a
string that gets re-expanded w/each call.

Theoretically the parsing of 'id' only happens at login.
I put them in an array, because if they are just in a 'string',
it's hard to tell the groups apart as they have spaces
in the names as well as spaces between the names...

The bash code ( I use to parse "id", FWIW):
# need to parse output of id, as it is only place we can notice groups
# with spaces in them! NOTE -- this must be done during 'bash_env' time

if [[ -z ${_GPSAFE_:-""} ]] 2>/dev/null ; then
   unset _GROUPS_
   typeset -Ax _GROUPS_

   function _idparse {
     # parse output of id:
     # uid=##(name) gid=##(name) groups=##(name)[,##(name)]...
     # Note, names may be 'absent' (in which case there are no parens).
     # grouplist is *comma* separated! -- but only on output of 'id';
     # I don't "idnames" can start with a number... (we'll assume not)
     # if group has no name, put it's number in as it's name
     # else you wouldn't see you are in those groups

     while read id ; do
       [[ $id =~ .?id= ]] && continue; #skip over uid/gid entries
       id="${id/\(/ }"
       # next line should work -- another bash bug...
       #[[ $id =~ ^[0-9]+$ ]] && id="$id $id"  #dup ID into missing name field
       gid="${id%% *}"
       name=${name##\ }
       [[ -z $name ]] && name="$gid"
     done  < <(id|sed -r '
       s/\) gid/\)\ngid/ ; s/\) groups/\)\ngroups/ ; s/\\/\\\\/g ;
       s/\),([0-9])/)\n\1/g ; s/\b([0-9]+),/\1\n/g ; s/groups=//')

   unset _GPSAFE_ 2>/dev/null ||:
   typeset -xr _GPSAFE_=$(typeset -p _GROUPS_) ||: # save away for future
   eval  $_GPSAFE_
Then I use it:

if [[ -n "${_GROUPS_[wheel]:-""}" ||
       -n "${_GROUPS_[root]:-""}" ||
       -n "${_GROUPS_[Administrators]:-""}" ]] ; then
   _path_prepend PATH /usr/local/sbin /usr/sbin /sbin

It's a hack for convenience, though if the perl routines don't work,
it might be the quickest solution....

You could also look in the code of 'id' to see how it gets
the groups (since it works... ;-))....

Problem reports:
Unsubscribe info:

More information about the Cygwin mailing list