2011-04-17 19:50:06 +0000 2011-04-17 19:50:06 +0000
377
377

重新加载Linux用户的组分配,而无需注销。

当使用

# usermod -G <grouplist> <user>

分配用户的二级组列表时,是否可以在不注销所有正在运行的会话的情况下强制该组分配生效?

0x1&

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

如果一个Screen会话中存在许多正在运行的shell,这将非常有用,因为整个会话基本上需要被销毁才能使组分配生效。

我想我可以在运行中的shell中使用 newgrp 命令来改变用户的主组–是否有其他方法可以用于次要组?

理想的情况是,我希望能在每个shell中生效,而不需要在每个shell中手动运行,但如果做不到这一点,也许可以强制Screen在每个shell中执行相同的命令。

答案 (12)

400
400
400
2011-11-06 15:28:07 +0000

在shell内部,你可以发出以下命令

su - $USER

id现在将列出新的组:

id
221
221
221
2011-10-10 17:36:48 +0000

很可怕的黑客,但你可以使用两层newgrp来实现这个目的:

id -g

…将给你当前的主组ID。在这个例子中,我们称它为orig_group。然后:

newgrp <new group name>

…将把你切换到该组作为主组,并将其添加到由groupsid -G返回的组列表中。现在,再来一个:

newgrp <orig_group>

…会给你一个shell,在这个shell中你可以看到新的组,而主组就是原来的组。

_编辑:这也不需要你输入密码,这也不需要你输入密码,而su会输入。

168
168
168
2013-06-18 16:27:30 +0000

这个妙招来自这个链接很好用!

exec su -l $USER

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

35
35
35
2014-12-17 21:33:21 +0000

1. 获得一个带新组的shell,而不需要再登录和再次登录

如果你只增加一个组,我用的是:

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

这是Legooolas的两层newgrp技巧的变种,但它是在一行中,不需要你手动输入主组。 sg的意思是新的shell取代了现有的shell,所以你不需要两次 “注销"。

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

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

Screen中的exec命令在你指定的任何窗口中运行命令(注意这是Screen命令,不是shell命令)。

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

screen -S <session_name> -X at \# stuff "exec sg <new_group_name> newgrp ### 1. 获得一个带新组的shell,而不需要再登录和再次登录


如果你只增加一个组,我用的是:

exec sg newgrp id -gn ”`

这是Legooolas的两层newgrp技巧的变种,但它是在一行中,不需要你手动输入主组。 at的意思是新的shell取代了现有的shell,所以你不需要两次 “注销"。

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

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

Screen中的id命令在你指定的任何窗口中运行命令(注意这是Screen命令,不是shell命令)。

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

id -gn### 1. 获得一个带新组的shell,而不需要再登录和再次登录

如果你只增加一个组,我用的是:

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

这是Legooolas的两层newgrp技巧的变种,但它是在一行中,不需要你手动输入主组。 stuff的意思是新的shell取代了现有的shell,所以你不需要两次 "注销"。

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

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

Screen中的[&007]&003命令在你指定的任何窗口中运行命令(注意这是Screen命令,不是shell命令)。

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

^M” “`

注意,需要转义回车,让&007在Screen会话中运行,并在命令结束时用^M让Screen点击 "回车"。因此,如果屏幕窗口中的一个窗口在命令提示符上有一个半写的命令,或者运行的是shell以外的应用程序(例如emacs, top),可能会发生一些奇怪的事情。如果这是一个问题,我有一些想法:

  • 要摆脱任何半写的命令,可以在命令的开头加上”^C"。

  • 为了避免在emacs窗口中运行该命令,你可以要求 “at "过滤窗口标题等(在上面的例子中,我使用了 ”#“,它匹配所有的窗口,但是你可以通过窗口标题、用户等来过滤)。

18
18
18
2016-10-07 04:53:42 +0000

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

newgrp <GroupName>

本博文有详细的解释。

12
12
12
2012-01-30 16:17:03 +0000

你可以这样做。

usermod -G添加你想要的组。然后,作为正在运行会话的用户,运行newgrp -,只需使用’-‘参数。你可以通过在当前会话中运行groupsusermod前后运行newgrp来验证。

这必须在每次打开的会话中运行–我不太了解屏幕。不过,如果能在所有的开放会话中迭代运行newgrp,应该就没问题了。你就不用担心知道组或组的ID了。

祝你好运。

11
11
11
2011-04-25 17:56:34 +0000

组通常是在登录时被枚举的,据我所知,没有办法在不注销和重新登录的情况下强迫它重新进行组枚举。

4
4
4
2017-02-10 23:21:38 +0000

总结一下:

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

使用 “exec "意味着用newgrp命令启动的新shell替换现有的shell(所以从新shell中退出会被注销)。newgrp -gpasswd命令不会影响现有进程;新添加的(或删除的!)组会出现在(从)你的帐户中,也就是在/etc/group和/etc/gshadow文件中,但现有进程的权限不会改变。要remove权限,你必须杀死任何运行中的进程;usermod不会重新读取/etc/group并重设组列表;相反,它似乎只是使用之前与进程关联的组。

1
1
1
2018-04-28 13:30:22 +0000

我无法让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
0
0
2014-08-06 14:03:21 +0000

如果你有sudo,这个功能可以让你在某些情况下省去多输入一次密码的麻烦:

sudo su $USER
0
0
0
2019-10-21 22:03:04 +0000

我需要在一个shell脚本中完成这个任务(脚本将当前用户添加到一个组中,然后运行需要该组成员资格的命令)。newgrp命令很脆,因为它只能运行一个新的shell,而不是任意的命令(我想用原始的命令行参数重新运行当前的shell脚本)。

以下是我的解决方案,它使用了很多bash-isms:(注意,周围的脚本需要某种分支,只有在所需的组当前不活动的情况下才会运行这个函数):

(注意:脚本暗示它运行了sudo adduser $user docker,这意味着它也可以直接运行sudo docker而不是docker,但在这种情况下,这是不可取的)

# save these for later
ORIGINAL_ARGS=("$@")

# This function is a little insane. The problem is this: user running
# this script is not a member of docker group, but used 'sudo' to add
# themselves to group. Without logging out and back in, the only way
# to gain access to that group is via the 'newgrp' command, which
# unfortunately starts a new shell rather than an arbitrary command...
#
# Also, we're going to newgrp twice: first to add the new group and
# again to restore the original group (but the new group remains in
# the 'groups' output).
#
# So this horrendous hack dups stdin to fd3 for later. Then runs
# 'newgrp' piping in a script that runs 'newgrp' a second time, piping
# in another script that restores stdin from fd3 and execs the
# original command...
restart-newgrp-newgrp() {
  # dup original stdin to fd3
  exec 3<&0

  local group="$1"
  local command="$0"
  local arg
  for arg in "${ORIGINAL_ARGS[@]}"; do
    printf -v command "%s %q" "$command" "$arg"
  done

  # restore original stdin from fd3; also replace any single-quote in
  # command with '"'"' to embed it in a single-quoted string
  local script
  printf -v script "exec newgrp %q <<<'exec <&3-; exec %s'" "$(id -gn)" "${command///\"\"}"

  exec newgrp "$group" <<<"$script"
}
0
0
0
2014-11-13 16:07:46 +0000

我也遇到了类似的问题,但也有未登录的用户。重启nscd没有帮助,但执行这个命令:nscd -i group。这应该会指示nscd(缓存守护进程)重新加载组文件。