Subject: bug#9987: [PATCH] groups,id: add -0, --null option

From: Pádraig Brady <[email-masked]>
Date: Wed, 18 Sep 2013 10:43:36 +0100

tl;dr

The is about being able to get a simple list of a
particular user's groups by doing `groups user`.
However it's probably best to not change the existing
output format of `groups` for a single argument
as we can just use `id` for this functionality.

On 09/16/2013 01:18 AM, Pádraig Brady wrote:
> On 09/03/2013 07:35 AM, Bernhard Voelker wrote:
>> On 09/02/2013 04:03 PM, Pádraig Brady wrote:

>>> It would be good I think to have a separate patch though
>>> that aligned with other systems and didn't output the
>>> "user:" at the start of the line when only a single user is specified.
>>
>> Interestingly, groups(1) doesn't seem to be specified by the
>> OpenGroup documents, only id(1):
>>   http://pubs.opengroup.org/onlinepubs/9699919799/utilities/id.html
>> Is there any other resource?
>>
>> But I agree, outputting the "user:" prefix for only one argument
>> seems to be silly.
> 
> If you could handle that as a separate patch it would be great.

On 09/17/2013 10:12 PM, Bernhard Voelker wrote:
> Hi Padraig,
>
> you wrote that it would be good to do this to "align with other
> systems". What systems do you refer to here?

Solaris and BSD at least. GNU is the outlier here.

>
> After thinking about it, I don't have a good feeling about it:
> a) such a change would possibly break existing scripts.
>    Okay, groups has never been intended to be used primarily
>    in scripts, but hey, we're planning to add --zero for that.

That's a fair point, but even such scripts might be immune.
If I wanted to process a list of user groups I would:

for user in 'me' 'you'; do
  for group in $(groups $user | sed 's/.*: //'); do
     echo processing $user:$group
  done
done

The sed manipulation still works with the proposed change.

> b) the new behavior would not be predictable anymore
>    in cases like
>      echo "$listofusers" | xargs groups
>    because xargs could exec a new groups process with just
>    one last argument left.

This is a fair point and would break scripts that did:

groups 'me' 'maybe_you' |
while read user _sep groups; do
  for group in $groups; do
    echo processing $user:$group
  done
done

Drats so changing output format based on the number of inputs is quite problematic.

We had the same tradeoff when adjusting basename to support multiple arguments.
On FreeBSD you must pass -a to get basename to process 2 args:
bsd$ basename 1 2
1
bsd$ basename 1 2 3
1
2
3
bsd$ basename -a 1 2
1
2

So we didn't mimic that behavior for the same reason,
and required the -a option to process all args:

GNU$ basename 1 2 3
basename: extra operand ‘3’
GNU$ basename -a 1 2 3
1
2
3

So how would we best select between the two output formats?
I wonder could we first look for the $USER env variable,
and if not empty, use getpwnam($USER) rather than getuid() etc.
So then you could select the simple output format for a specific user like:

  USER=whatever groups

I'm worried of some cases though where USER might not be accurate,
and it's probably not portable (USERNAME and LOGNAME used elsewhere).

So we're probably best use an option if we're going to change this at all.
If we were to do that --user would probably be best.

However we already have this functionality from `id -Gn` so it's not
worth change `groups` to do this.

I'll send a doc patch later for the groups command to summarize to
use `id -Gn` for cases like this, and in general since it's more
portable and POSIX standardized.

thanks!
Pádraig.