1

I'd like to create a new group in a script, assign the current user to it, reload the user's groups and continue executing commands that require the new group.

In this related question I found nice ways of avoiding spawning a new inner shell that I would eventually have to exit out of to get to the current one where the script is running. But the problem is that exec replaces the current shell altogether, so the script halts. For example:

#!/bin/bash
exec sg GROUP newgrp $(id -gn)
echo hello

Here the script switches the group alright and avoids needing a double exit (say via SSH), but echo is never run.

I could run a different script with sg with the commands that require that group and then have the final group update at the end of the script just to be kind to the user, but that seems suboptimal. Is there a way to update group assignments cleanly while running a script?

Felix
  • 221

1 Answers1

0

Unfortunately, the only way that I know of to get a shell with up-to-date user groups is to do something like su - $(whoami), which requires the current user to type their password in again, or use newgrp / sg. To avoid the user needing to authenticate again, we are stuck with the latter.

#!/bin/bash

The new group that will be created and have the current user added to.

GROUP_NEW=testgroup

if [ -z "$GROUPS_LIST_ADDED" ]; then sudo groupadd "$GROUP_NEW" sudo usermod --append --groups "$GROUP_NEW" "$(whoami)"

# Run this script again with the new group added to the groups list
# and set as the primary group. We will run it once more to restore
# the primary group to the original value.
export GROUP_ORIGINAL="$(id -gn)"
export GROUPS_LIST_ADDED=1
# We ensure that script arguments are independently sub-quoted.
exec sg "$GROUP_NEW" "exec '$0' $(printf "'%s' " "$@")"

elif [ -z "$GROUP_PRIMARY_RESTORED" ]; then # Rerun this script once more to restore the primary group. export GROUP_PRIMARY_RESTORED=1 exec sg "$GROUP_ORIGINAL" "exec '$0' $(printf "'%s' " "$@")" fi

Continue on with this script. The current user now has the new group added to

it's groups list.

id

We need to re-executue using sg twice, once to add the new group to the "groups list" and another to set the "primary group" back to the original primary group. If we tried to do this in one line of nested execs, we would have to use double escaped quotes for the script's arguments, which is complex and unclear. For this reason, I chose to split the sg exec calls.

Craig H
  • 68
  • 5