重新加载Linux用户的组分配而不注销


348

使用以下方式分配用户的辅助组列表时:

# usermod -G <grouplist> <user>

是否可以强制此组分配在不注销所有正在运行的会话的情况下生效?

在存在许多运行中的Shell 的Screen会话的情况下,这将非常有用,因为整个会话本质上需要销毁才能使组分配生效。

我想我可以使用newgrp命令在运行的外壳程序中更改用户的主要组-是否有一些替代方案可用于次要组?

理想情况下,我希望某些东西可以在每个shell中生效,而不必在每个shell中手动运行,但是如果失败了,也许可以通过某种方式强制Screen在每个shell中执行相同的命令。


我知道,至少对于某些窗口/会话管理器而言,这样做是可能的,这样会话可以选择新组,并且可用于从菜单,面板按钮或其他任何开始的任何新进程。我刚才来这里只是想再次找到它,所以现在不能说怎么做,这可能是特定于窗口管理器的。
mc0e 2015年

Answers:


205

骇人听闻,但您可以使用两层newgrp来实现特定组的目标:

id -g

...将为您提供当前的主要组ID。orig_group在本示例中,我们将其称为。然后:

newgrp <new group name>

...将切换到该组作为主要组,并将其添加到groups或返回的组列表中id -G。现在,进一步:

newgrp <orig_group>

...将为您提供一个外壳,您可以在其中看到新组,而主要组是原始组。

这太可怕了,一次只能为您添加一个组,但是它帮了我几次,无需注销/在我的整个X会话中就可以添加组(例如,将熔断器作为一个组添加到一个用户中)这样sshfs就可以使用)。

编辑:这也不需要您输入密码su


6
不错的技巧,我喜欢
Simon

1
在Fedora上,我不得不newgrp $USER代替newgrp <orig_group>。这意味着我不必查找原始的主组ID,因此比该解决方案还要容易。
理查德·特纳

2
我发现这样做就足够了newgrp <new group name>。这是Ubuntu 14.04
Edward Falk

4
@EdwardFalk正确,但您不想(可能不希望)让该小组成为您的主要成员……
mimoralea

4
请注意,每个newgrp创建一个新的外壳程序,因此当您需要从会话中完全退出时,您需要执行“退出退出出口”以完全退出(:
jwd

370

从外壳内部,您可以发出以下命令

su - $USER

id现在将列出新组:

id

3
我认为这在许多情况下是最好的方法,但是原始的发布者确实希望在屏幕会话中更新多个外壳。该解决方案将在每个外壳上完成。
Adrian Ratnapala 2011年

3
妙招,很棒!
genpfault

4
原始解决方案也只能在屏幕中修复单个shell会话。我刚刚测试过。该解决方案有效的原因是因为您正在生成一个完整的新会话,而不是从原始环境继承。
Dror 2014年

4
这确实应该是公认的答案。好招,谢谢!
dotancohen

2
但是,这需要您输入密码,如果您尝试在多个会话中输入密码,可能会很麻烦/不需要。
Legooolas

155

这个链接的巧妙技巧非常有用!

exec su -l $USER

我想我会在这里张贴它,因为每次我忘记怎么做时,这是google中出现的第一个链接。


14
+1用于不将用户置于子外壳中;您可以像往常一样注销/退出。另外,如果在/ etc / sudoers中设置了NOPASSWD:,则可以使用exec sudo su -l $USER来避免提示您输入密码。
伊万X

21
请注意:系统将要求您输入sudo密码。如果弄错了,终端将关闭。
泰勒·科利尔

1
@TylerCollier伊万没有提到NOPASSWD:
pepoluan

32

1.使用新组的外壳,而无需注销和再次登录

如果您仅添加一个组,则使用以下命令:

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

这是对Legooolas的两层newgrp技巧的一种变体,但是它只是一行,不需要您手动输入主要组。

sg是newgrp,但接受使用新组ID执行的命令。这exec意味着新外壳将替换现有外壳,因此您无需两次“注销”。

与使用su不同,您无需输入密码。它还不会刷新您的环境(除了添加组之外),因此您保留了当前的工作目录等。

2.在会话的所有“屏幕”窗口中执行命令

at在屏幕命令运行你指定的任何窗口(注意这是一个屏幕的命令,而不是一个shell命令)的命令。

您可以使用以下命令将命令发送到所有现有的Screen会话:

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

请注意,需要避免反引号以id在Screen会话中运行,而^ M则使Screen在命令末尾命中“ enter”。

还要注意,屏幕的stuff命令只是代表您键入命令文本。因此,如果其中一个屏幕窗口在命令提示符下具有半写命令或正在运行除外壳程序以外的应用程序(例如emacs,top),则可能会发生奇怪的事情。如果这是一个问题,我有一些想法:

  • 要摆脱任何半写命令,可以在命令开头添加“ ^ C”。
  • 为了避免在emacs窗口等中运行命令,您可以要求`at'过滤窗口标题等(在上面的示例中,我使用“#”,它匹配所有窗口,但是您可以按窗口标题,用户进行过滤等)。

要在特定窗口(由窗口号标识)中运行命令,请使用以下命令:

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

太棒了,似乎还没有其他副作用,谢谢!
西里尔·杜尚


12

通常在登录时会枚举组,我知道没有办法强迫它在不注销并重新登录的情况下重新进行组枚举。

在这里投票的许多答案似乎都使​​用一种变通方法,该方法调用具有新环境的新Shell(与再次登录相同)。父shell和所有其他连续运行的程序通常直到干净的注销和登录后才从新的shell重新调用之前,通常不会获得新的组成员身份。


说实话,我非常确定这不是真的-之前我已经在Linux机器上找到了一种方法来做到这一点。但是,对于我的一生,我不记得命令是什么。如果找到它,我将其发布。编辑:刚找到它,我将其发布为答案。
Lunchmeat317 2012年

1
感谢您指出这一点,这也是我的理解。此处的所有其他答案都只是打开一个新的外壳,而不管它是替换一个打开的外壳还是重新启动屏幕或其他任何操作。没有神奇的灵丹妙药可以发出命令或脚本,并且每个正在运行的会话(包括您的X会话)都可以反映新的组成员身份。
scravy

12

你可以这样做。

使用添加任意多个组usermod -G。然后,作为具有运行会话的用户,newgrp -仅使用'-'参数运行。

这会将组ID重新初始化为默认值,但也会同时设置辅助组。您可以通过运行验证这一点groups从当前会话中,前,后usermodnewgrp

这必须在每个打开的会话中运行-我对屏幕了解不多。但是,如果可以遍历所有打开的会话并运行newgrp,那么您应该很好。您无需担心知道组或组ID。

祝您好运。


11
尝试在X会话中的xterm上运行,但不起作用
dwery 2012年

3
尝试在tmux中的一个会话上,但也没有在那里工作
Michael

2
在Amazon linux 2上试用过,但无法正常工作
Cyril Duchon-Doris

1
newgrp -开始新的外壳程序
Piotr Findeisen

根据您对Mister_Tom答案的评论,与其他所有答案一样,这是一种解决方法。Mister_Tom的答案仍然正确。
scravy

4

总结一下:

exec newgrp <newlyaddedgroupname1>
exec newgrp <newlyaddedgroupname2>
...
exec newgrp -

使用'exec'意味着用newgrp命令启动的新外壳替换现有外壳(因此退出新外壳会使您注销)。

最后newgrp -需要恢复正常的主要组,因此您以后创建的文件将具有该文件作为其组所有者。

注意:原始发布者的问题是如何使新添加的组在现有过程中可见。该gpasswdusermod命令不会影响现有的流程; 新添加(或删除!)的组会出现在您的帐户中(或从中消失),即在/ etc / group和/ etc / gshadow文件中,但不会更改现有进程的权限。要删除权限,您必须终止所有正在运行的进程。newgrp -不会重新读取/ etc / group并重置组列表;相反,它似乎仅使用先前与该流程关联的组。


顺便说一句,exec su - <username>可用于获取具有组设置的新登录Shell,但在脚本中将无法使用,因为新Shell将读取终端的命令。您可以su -c "command ..." <myusername>用来重新启动脚本,但是生成的进程没有控制终端,因此,如果尝试使用屏幕编辑器或其他交互式命令,则会发生错误。
jimav

为什么这被否决?有人可以解释一下这是什么坏事,因为那是我的经历,我想我最喜欢它?
jasonmp85 '17

Gah,我在测试前将其投票通过。newgrp -没有取代“主要组”。帕特里克·康海蒂(Patrick Conheady)的答案是最好的答案,因为它既不分叉也不改变主要群体。
jasonmp85 '17

1

我有类似的问题,但也适用于未登录的用户。NSCD的重启并没有帮助,但执行这个命令所做的:nscd -i group。那应该指示nscd(缓存守护程序)重新加载groups文件。


1

我无法使newgrp命令正常工作。我不确定这是否取决于/ etc / sudoers,但是通常我必须输入sudo的密码,并且这种方法不需要我的密码即可:

[leo60228@leonix:~]$ groups
users wheel

[leo60228@leonix:~]$ sudo echo hi
[sudo] password for leo60228:
hi

[leo60228@leonix:~]$ sudo -k # reset sudo timeout

[leo60228@leonix:~]$ exec sudo -i -u $(whoami) # no password necessary

[leo60228@leonix:~]$ groups
users wheel docker

0

如果您有这种方法sudo,那么就可以解决问题,在某些情况下,可以避免再次输入密码:

sudo su $USER
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.