Reload a Linux user's group assignments without logging out

383,051

Solution 1

Horribly hacky, but you could use two layers of newgrp to achieve this for a particular group:

id -g

...will give you the current primary group ID. We'll call this orig_group for the purposes of this example. Then:

newgrp <new_group_name>

...will switch you to that group as the primary and add it to the list of groups returned by groups or id -G. Now, a further:

newgrp <orig_group_name>

...will get you a shell in which you can see the new group and the primary is the original one.

This is horrible and will only get you one group added at a time, but it has helped me out a couple of times to get groups added without logging out/in my whole X session (e.g. to get fuse added as a group to a user so that sshfs will work).

Notes:

  • This doesn't require you to type your password either, which su will

  • Each call to newgrp launches a new shell (as a child of the current shell)

  • The current shell can be "replaced" with the exec command

    exec newgrp <new_group_name>
    
  • Using exec will resolve the caching issue for the current branch of the pstree

    I.e. if you are logged in to a window manager, every new terminal you launch will be a child of an earlier branch than the one "corrected" by this exercise and will therefore inherit the cached gid map.

Solution 2

From inside a shell, you can issue the following command

su - $USER

id will now list the new group:

id

Solution 3

This nifty trick from this link works great!

exec su -l $USER

I figured I'd post it here as every time I forget how to do this, this is the first link that come up in google.

Solution 4

1. Getting a shell with the new group without logging out and in again

If you're only adding one group, I used the following:

exec sg <new group name> newgrp `id -gn`

This is a variation on Legooolas's two-layer newgrp trick, but it is in one line and doesn't require you to manually enter your primary group.

sg is newgrp but accepting a command to execute with the new group ID. The exec means that the new shell replaces the existing shell, so you don't need to "logout" twice.

Unlike using su, you don't need to type in your password. It also doesn't refresh your environment (other than adding the group), so you retain your current working directory etc.

2. Executing the command in all Screen windows in a session

The at command in Screen runs a command in whatever windows you specify (note this is a Screen command, not a shell command).

You can use the following command to send the command to all an existing Screen sessions:

screen -S <session_name> -X at \# stuff "exec sg <new_group_name> newgrp \`id -gn\`^M"

Note the need to escape the backticks to get id to run in the Screen session, and the ^M to get Screen to hit 'enter' at the end of your command.

Note also that screen's stuff command simply types the command text on your behalf. Therefore something strange may happen if one of the screen windows has a half-written command at a command prompt or is running an application other than a shell (e.g. emacs, top). If this is an issue, I have some ideas:

  • To get rid of any half-written command, you can add "^C" to the start of the command.
  • To avoid running the command in an emacs window, etc, you could ask `at' to filter on window title etc (in the example above, I use "#", which matches all windows, but you can filter by window title, user, etc).

To run the command in a specific window (identified by window number), use the following:

screen -S <session_name> -p 0 -X stuff "exec sg <new_group_name> newgrp \`id -gn\`^M"

Solution 5

Using newgrp command solved problem for me:

newgrp <GroupName>

This blog post has detailed explanation.

Share:
383,051

Related videos on Youtube

Simon
Author by

Simon

Updated on September 18, 2022

Comments

  • Simon
    Simon over 1 year

    When assigning a user's secondary group list using:

    # usermod -G <grouplist> <user>
    

    is it possible to force this group assignment to take effect without logging out all running sessions?

    This would be very useful in the situation where a Screen session exists with many running shells, as the entire session essentially needs to be destroyed to make the group assignment take effect.

    I think I can change the user's primary group in a running shell using the newgrp command - is there some alternative that would work for secondary groups?

    Ideally, I'd want something that would take effect in each shell without being run manually in every one, but failing that, maybe some way of forcing Screen to execute the same command in each.

    • mc0e
      mc0e over 8 years
      I know that at least for some window / session managers it's possible to do this such that the session picks up the new group and it's available to any new processes started from the menus, panel buttons or whatever. I came here just now looking to find that again, so can't say just now how to do it, and it's probably specific to the window manager.
  • Adrian Ratnapala
    Adrian Ratnapala over 12 years
    I think this the best approach in many cases, but the original poster did want to update multiple shells within a screen session. This solution would have be be done from each shell.
  • lunchmeat317
    lunchmeat317 over 12 years
    Truthfully, I'm pretty sure that this isn't true - I'd found a way to do it before on a Linux box. However, for the life of me, I cannot remember what the command was. If I find it, I'll post it. Edit: Just found it, I'm posting it as an answer.
  • Michael
    Michael about 11 years
    tried in on a session in tmux and it did not work there either
  • ahmed afzaal
    ahmed afzaal over 10 years
    On Fedora I had to do newgrp $USER instead of newgrp <orig_group>. That means I didn't have to find my original primary group ID, so it's even easier than this solution.
  • Dror
    Dror about 10 years
    The original solution would also only fix a single shell session in screen. I just tested that. The reason this solution works is because you are spawning a complete new session rather than inheriting from the original environment.
  • Ivan X
    Ivan X over 9 years
    +1 for not putting the user in a subshell; you can logout/exit as usual with this. Also, if NOPASSWD: is set in /etc/sudoers, you can instead use exec sudo su -l $USER to avoid being prompted for password.
  • Tyler Collier
    Tyler Collier about 9 years
    Be advised: you'll be asked for a sudo password. If you get it wrong, your terminal will close.
  • bmaupin
    bmaupin about 9 years
    You can make the command slightly more generic like so: su - $USER
  • Legooolas
    Legooolas almost 9 years
    This also doesn't require a password, which su does.
  • Edward Falk
    Edward Falk about 8 years
    I found it was sufficient to do newgrp <new group name>. This was Ubuntu 14.04
  • Legooolas
    Legooolas about 8 years
    This requires you to type a password though, which might be awkward/unwanted if you are trying to do it in lots of sessions.
  • mimoralea
    mimoralea almost 8 years
    @EdwardFalk right, but you don't (might not) want to leave that group as your primary...
  • Raffi
    Raffi over 7 years
    For new group name I had to specify the group that was missing from the first id.
  • user3467349
    user3467349 over 7 years
    This doesn't seem to work... newgrp -<orig_group> will resolve to a login that doesn't include the <new_group_name>.. Are you sure this answer is still functional?
  • pepoluan
    pepoluan over 7 years
    @user3467349 where does that dash - before <orig_group> come from? The command should be newgrp <orig_group> <== notice, no dash
  • pepoluan
    pepoluan over 7 years
    @TylerCollier Ivan did mention NOPASSWD:
  • user3467349
    user3467349 over 7 years
    The - was a typo but your answer 100% doesn't work.
  • user3467349
    user3467349 over 7 years
    try it: groupadd example_group; sudo usermod -aG example_group; original_group=$(id -gn); newgrp example_group; newgrp $original_group; than look at the output of groups. example_group is not in there.
  • jwd
    jwd over 7 years
    Note that each newgrp creates a new shell, so when you need to fully exit from your session you need to do "exit exit exit" to get all the way out (:
  • jimav
    jimav about 7 years
    By the way, exec su - <username> can be used to get a new login shell with groups set, but that won't work in scripts because a new shell will read commands from the terminal. You could use su -c "command ..." <myusername> to restart your script, but the resulting process has no controlling terminal and so an error will occur if a screen editor or other interactive command is attempted.
  • jasonmp85
    jasonmp85 about 7 years
    Why was this downvoted? Can someone explain what's bad about it, because it was what occurred to me and I think I like it best?
  • jasonmp85
    jasonmp85 about 7 years
    Gah, I voted it up before testing. newgrp - does not replace the "primary group". Patrick Conheady's answer is the best one here, as it neither forks nor changes the primary group.
  • Pablo A
    Pablo A almost 7 years
    Could you please explain what does this? Also would be great why is better or the differences with other solutions like newgrp - and exec su -l $USER.
  • Cyril Duchon-Doris
    Cyril Duchon-Doris about 6 years
    Tried on Amazon linux 2, it did not work
  • Piotr Findeisen
    Piotr Findeisen about 6 years
    newgrp - starts a new shell process
  • Gringo Suave
    Gringo Suave about 6 years
    The one below with exec is a bit better, doesn't create a subshell.
  • rickfoosusa
    rickfoosusa almost 6 years
    Didn't work on Ubuntu 18.04. Asked for password and failed. newgrp docker resulted in newgrp: failed to crypt password with previous salt: Invalid argument. su method below worked.
  • crockeea
    crockeea about 5 years
    See stackoverflow.com/a/10080117/925978 for how to do this inside a script; you need heredocs.
  • Tacahiroy
    Tacahiroy over 4 years
    @jwd You can avoid exit; exit; exit you could use exec to replace the current shell like exec newgrp new_group, then exec newgrp orig_group.
  • scravy
    scravy over 4 years
    In light of your comment on the answer by Mister_Tom, this is, as all of the other answers, a workaround. Mister_Tom's answer is still correct.
  • scravy
    scravy over 4 years
    Thank you for pointing this out, this is also my understanding. Every other answer here simply opens a new shell, no matter whether it replaces one open shell or restarts screen or whatever. There is no magical panacea to issue a command or script and have every running session, including your X session, reflect the new group memberships.
  • nijoakim
    nijoakim over 4 years
    Note that you won't be able to run X applications without doing export DISPLAY=:0.0 after su - $USER. (Or replace ":0.0" with whatever echo $DISPLAY outputs.)
  • neokyle
    neokyle over 4 years
    This only works for an interactive shell, If you try to put it in a bash.sh script as soon as this command is run the script will stop. On this related question, unix.stackexchange.com/questions/18897/…, Gilles points out that this is just the way Linux processes work. Ansible will let you refresh group but it only works for ssh connections not localhost stackoverflow.com/questions/26677064/… For localhost I've worked around it by using EC2's Userdata to pre-add the group before my first login.
  • Hermann Schwarz
    Hermann Schwarz over 4 years
    su - your_login is the most elegant and simple way.
  • Sam Johnson
    Sam Johnson about 4 years
    only thing that worked for me trying to get docker to work without restarting because I had a huge job running
  • tom
    tom about 4 years
    Really nice answer. Small correction: sg expects the command to be a single argument, and ignores further arguments (try sg some_group echo test). So sg new_group_name newgrp `id -gn` is actually equivalent to sg new_group_name newgrp. The reason it seems to work is that when newgrp is invoked with no arguments it uses the default group in /etc/passwd, which usually matches the current group. The fix is to quote the command: sg new_group_name "newgrp `id -gn`"
  • errolflynn
    errolflynn about 4 years
    Two notes: (1) After running this I could not open X applications in this shell [Archlinux, Surface Book 2]. (2) This only works for the current shell. Else it is a good solution.
  • Akito
    Akito over 3 years
    The best answer so far. However, if you create an error (e.g. due to providing an invalid password for the specified user) then your current shell will just close, as a result of that error.
  • Alex
    Alex over 3 years
    This is the best answer!!!
  • Frank Nocke
    Frank Nocke over 3 years
    interesting! this is one of few or the only session, that doesn not spawn a new session.
  • bitoffdev
    bitoffdev about 3 years
    On Ubuntu 20.x, I found the stock newgrp command would not accept the numeric user id returned by the stock id -g command, but it does accept the textual user name as returned by id -gn, or alternatively $USER in most cases.
  • smac89
    smac89 about 3 years
    This only works for the current shell you're in. As soon as you exit the shell, you loose the group setting again. I ended up just logging out and back in. Much faster TBH
  • Admin
    Admin almost 2 years
    WARNING: When you mistype your password, it will log you out of your current shell! Which is exactly what I came here to avoid, goddammit!
  • Admin
    Admin almost 2 years
    @tom: if newgrp without arguments uses the default group, why bother with newgrp $(id -gn) at all? sg new_group_name newgrp is all that is needed, correct?
  • Admin
    Admin almost 2 years
    @MestreLion: The reason for id -gn is to preserve the user's current group ID in the case where the current group it is not the default group. In most cases the user's current group will be their default group, and in that case sg <new_group_name> newgrp would be fine.
  • Admin
    Admin almost 2 years
    @tom: wow, so that snippet "loads" a new group and then is careful enough to "revert" to the user's previously current group? Sweet! Wish I could upvote more. Suggestion: replace backticks with $(), far easier to read and also standard on most (all?) shells
  • Admin
    Admin almost 2 years
    @MestreLion: Yes (like the double-newgrp trick from Legooolas' answer). I personally prefer $(), but some non-POSIX shells such as tcsh don't support it (demo). I suggested an edit to fix the issue with sg, but left the backticks to respect the author's preference.