无需注销即可重新加载 Linux 用户的组分配

Sim*_*mon 468 linux debian shell permissions gnu-screen

使用以下方法分配用户的次要组列表时:

# usermod -G <grouplist> <user>
Run Code Online (Sandbox Code Playgroud)

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

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

我想我可以使用newgrp命令在正在运行的 shell 中更改用户的主要组- 是否有一些适用于次要组的替代方法?

理想情况下,我想要一些可以在每个 shell 中生效的东西,而无需在每个 shell 中手动运行,但如果失败,可能是某种强制 Screen 在每个 shell 中执行相同命令的方法。

sti*_*vlo 494

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

su - $USER
Run Code Online (Sandbox Code Playgroud)

id 现在将列出新组:

id
Run Code Online (Sandbox Code Playgroud)

  • 原始解决方案也只能修复屏幕中的单个 shell 会话。我刚刚测试过。此解决方案有效的原因是您正在生成一个完整的新会话,而不是从原始环境继承。 (4认同)
  • 我认为这是在许多情况下的最佳方法,但原始海报确实希望在屏幕会话中更新多个 shell。这个解决方案应该是从每个 shell 完成的。 (3认同)
  • 您可以使命令稍微更通用,如下所示:`su - $USER` (2认同)
  • 这需要您输入密码,如果您尝试在很多会话中输入密码,这可能会很尴尬/不需要。 (2认同)
  • 请注意,如果不在“su - $USER”之后执行“export DISPLAY=:0.0”,您将无法运行 X 应用程序。 (或者将“:0.0”替换为任何“echo $DISPLAY”输出。) (2认同)

Leg*_*las 265

可怕的hacky,但您可以使用两层newgrp来为特定组实现这一目标:

id -g
Run Code Online (Sandbox Code Playgroud)

...将为您提供当前的主要组 ID。orig_group出于本示例的目的,我们将调用它。然后:

newgrp <new group name>
Run Code Online (Sandbox Code Playgroud)

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

newgrp <orig_group>
Run Code Online (Sandbox Code Playgroud)

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

这太可怕了,一次只会让你添加一个组,但它帮助我几次在不注销/在我的整个 X 会话中添加组(例如将保险丝作为一个组添加到用户这样 sshfs 就可以工作了)。

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

  • @EdwardFalk 是的,但您不想(可能不想)将该组作为您的主要... (7认同)
  • @jwd 你可以避免`exit; 出口; exit` 你可以使用`exec`来替换当前的shell,比如`exec newgrp new_group`,然后是`exec newgrp orig_group`。 (7认同)
  • 请注意,每个 `newgrp` 都会创建一个新的 shell,因此当您需要完全退出会话时,您需要执行“exit exit exit”以完全退出(: (5认同)
  • 我发现执行 `newgrp &lt;new group name&gt;` 就足够了。这是 Ubuntu 14.04 (3认同)
  • 在 Fedora 上,我必须使用 `newgrp $USER` 而不是 `newgrp &lt;orig_group&gt;`。这意味着我不必找到我原来的主要组 ID,所以它比这个解决方案更容易。 (2认同)
  • 有关如何在脚本中执行此操作,请参阅 /sf/answers/705608221/;你需要heredocs。 (2认同)
  • 在 Ubuntu 20.x 上,我发现 stock `newgrp` 命令不接受 stock `id -g` 命令返回的数字用户 id,但它确实接受 `id -gn` 返回的文本用户名,或者在大多数情况下,也可以选择“$USER”。 (2认同)

jha*_*sma 210

链接中的这个绝妙技巧非常有效!

exec su -l $USER
Run Code Online (Sandbox Code Playgroud)

我想我会在这里发布它,因为每次我忘记如何执行此操作时,这是 google 中出现的第一个链接。

  • 请注意:系统会要求您输入 sudo 密码。如果您弄错了,您的终端将关闭。 (25认同)
  • +1 表示没有将用户置于子 shell 中;你可以像往常一样注销/退出。此外,如果在 /etc/sudoers 中设置了 NOPASSWD:,您可以改为使用 `exec sudo su -l $USER` 来避免提示输入密码。 (24认同)

Pat*_*ady 43

1. 无需注销并重新登录即可获得新组的外壳

如果您只添加一组,我使用了以下内容:

exec sg <new group name> newgrp `id -gn`
Run Code Online (Sandbox Code Playgroud)

这是 Legooolas 的两层 newgrp 技巧的变体,但它在一行中并且不需要您手动输入您的主要组。

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

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

2.在一个会话中的所有Screen窗口中执行命令

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

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

screen -S <session_name> -X at \# stuff "exec sg <new_group_name> newgrp \`id -gn\`^M"
Run Code Online (Sandbox Code Playgroud)

请注意需要转义反引号才能id在 Screen 会话中运行,并且需要转义^M 才能让 Screen 在您的命令结束时点击“输入”。

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

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

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

screen -S <session_name> -p 0 -X stuff "exec sg <new_group_name> newgrp \`id -gn\`^M"
Run Code Online (Sandbox Code Playgroud)

  • 真的很好的答案。小更正:`sg` 期望命令是单个参数,并忽略更多参数(尝试 `sg some_group echo test`)。所以``sg new_group_name newgrp `id -gn``` 实际上相当于`sg new_group_name newgrp`。它似乎有效的原因是,当不带参数调用 `newgrp` 时,它使用 /etc/passwd 中的默认组,它通常与当前组匹配。修复方法是引用命令:``sg new_group_name "newgrp `id -gn`"`` (3认同)

小智 23

使用newgrp命令为我解决了问题:

newgrp <GroupName>
Run Code Online (Sandbox Code Playgroud)

这篇博文有详细的解释。


Mis*_*Tom 14

组通常在登录时枚举,我知道没有办法强制它重新进行组枚举而不注销并重新登录。

此处投票的许多答案似乎都使​​用了一种解决方法,该方法会调用具有新环境的新 shell(与再次登录相同)。父 shell 和所有其他持续运行的程序通常不会收到新的组成员身份,直到通常在干净的注销和登录后从新的 shell 重新调用。

  • 谢谢你指出这一点,这也是我的理解。这里的每个其他答案都只是打开一个新的外壳,无论它是替换一个打开的外壳还是重新启动屏幕或其他任何东西。没有灵丹妙药可以发出命令或脚本并使每个正在运行的会话(包括您的 X 会话)反映新的组成员身份。 (2认同)

小智 12

你可以这样做。

使用usermod -G.添加任意数量的组。然后,作为正在运行会话的用户,newgrp -只使用“-”参数运行。

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

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

祝你好运。

  • 在 X 会话中尝试使用 xterm,但没有奏效 (11认同)
  • 在 tmux 中尝试了一个会话,但它也没有在那里工作 (3认同)
  • 在 Amazon linux 2 上试过,没用 (2认同)
  • `newgrp -` 启动一个新的 shell 进程 (2认同)

小智 5

如果您需要保留环境变量,请尝试exec sudo -E -u "$USER" "$SHELL". exec用新的 shell 替换当前的 shell,-E保留环境,-u "$USER"将用户更改为您自己,并$SHELL指定该 shell 是要使用的命令。


nya*_*u64 5

要重生终端但保持 GUI 应用程序正常运行,请尝试exec su -p $USER. 这会保留环境变量(包括 Xorg 内容)但会重新加载组。

或者删除exec以生成子 shell,而不是替换当前 shell。