Перезагрузите назначения группы пользователей Linux без выхода

При назначении списка вторичных групп пользователя с помощью:

# usermod -G <grouplist> <user>

Можно ли заставить это групповое назначение вступить в силу без выхода из всех запущенных сеансов?

Это было бы очень полезно в ситуации, когда существует сеанс Screen со многими запущенными оболочками, поскольку весь сеанс необходимо уничтожить, чтобы назначение группы вступило в силу.

Я думаю, что я могу изменить основную группу пользователя в работающей оболочке, используя newgrp Команда - есть ли альтернатива, которая будет работать для вторичных групп?

В идеале, я хотел бы, чтобы что-то действовало в каждой оболочке без ручного запуска в каждой, но без этого, может быть, каким-то способом заставить Screen выполнять одну и ту же команду в каждой.

11 ответов

Решение

Ужасно хаки, но вы могли бы использовать два слоя newgrp чтобы достичь этого для определенной группы:

id -g

... даст вам текущий идентификатор основной группы. Мы назовем это orig_group для целей этого примера. Затем:

newgrp <new group name>

... переключит вас на эту группу в качестве основной и добавит ее в список групп, возвращаемых groups или же id -G, А теперь еще:

newgrp <orig_group>

... достанет вам оболочку, в которой вы сможете увидеть новую группу, а основная - оригинальная.

Это ужасно и приведет к добавлению только одной группы за один раз, но это помогло мне пару раз добавлять группы без выхода из системы / во время всего сеанса X (например, для добавления предохранителя как группы для пользователя так что sshfs будет работать).

Изменить: Это не требует, чтобы вы набрали свой пароль, который su будут.

Внутри оболочки вы можете выполнить следующую команду

su - $USER

id теперь перечислит новую группу:

id

Этот отличный трюк по этой ссылке прекрасно работает!

exec su -l $USER

Я решил опубликовать это здесь, так как каждый раз, когда я забываю, как это сделать, это первая ссылка, которая появляется в Google.

1. Получение оболочки с новой группой без выхода и повторного входа

Если вы добавляете только одну группу, я использовал следующее:

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

Это разновидность двухслойного трюка Легуоласа с newgrp, но он в одну строку и не требует ручного входа в основную группу.

sg является newgrp, но принимает команду для выполнения с новым идентификатором группы. exec означает, что новая оболочка заменяет существующую, поэтому вам не нужно дважды выходить из системы.

В отличие от использования su, вам не нужно вводить пароль. Он также не обновляет вашу среду (кроме добавления группы), поэтому вы сохраняете текущий рабочий каталог и т. Д.

2. Выполнение команды во всех окнах экрана в сеансе

at команда в Screen запускает команду в любых окнах, которые вы укажете (обратите внимание, что это команда Screen, а не команда оболочки).

Вы можете использовать следующую команду, чтобы отправить команду всем существующим сеансам экрана:

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

Обратите внимание на необходимость избежать кавычек, чтобы получить id чтобы запустить в сеансе экрана, и ^M, чтобы получить экран, чтобы нажать "Enter" в конце вашей команды.

Обратите внимание также, что экран stuff Команда просто набирает текст команды от вашего имени. Поэтому может произойти что-то странное, если одно из окон экрана имеет наполовину написанную команду в командной строке или запускает приложение, отличное от оболочки (например, emacs, top). Если это проблема, у меня есть несколько идей:

  • Чтобы избавиться от любой наполовину написанной команды, вы можете добавить "^C" в начало команды.
  • Чтобы избежать запуска команды в окне emacs и т. Д., Вы можете попросить `at'отфильтровать заголовок окна и т. Д. (В приведенном выше примере я использую"#", который соответствует всем окнам, но вы можете фильтровать по заголовку окна, пользователю, так далее).

Чтобы запустить команду в определенном окне (определяется номером окна), используйте следующее:

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

С помощью newgrp Команда решила проблему для меня:

newgrp <GroupName>

Этот пост имеет подробное объяснение.

Группы обычно перечисляются при входе в систему, и я не знаю, как заставить его заново выполнить перечисление групп без выхода из системы и повторного входа.

Многие ответы, отобранные здесь, похоже, используют обходной путь, который вызывает новую оболочку со свежей средой (аналогично повторному входу в систему). родительская оболочка и все другие постоянно работающие программы, как правило, не получат членство в новой группе, пока их не вызовут из новой оболочки, обычно после чистого выхода из системы и входа в систему.

Вы можете сделать это.

Добавьте столько групп, сколько хотите, используя usermod -G, Затем, как пользователь с запущенным сеансом, запустите newgrp - только с аргументом "-".

Это приводит к повторной инициализации идентификатора группы по умолчанию, но также устанавливает и вторичные группы. Вы можете проверить это, запустив groups от текущего сеанса до и после usermod и newgrp,

Это должно выполняться из каждого открытого сеанса - я не знаю много о экране. Тем не менее, если возможно перебрать все открытые сессии и запустить newgrp, ты должен быть хорошим. Вам не нужно беспокоиться о знании групп или идентификаторов групп.

Удачи вам.

Если вам нужно сохранить переменные среды, попробуйте exec sudo -E -u "$USER" "$SHELL". exec заменяет текущую оболочку на новую, -E сохраняет окружающую среду, -u "$USER" меняет пользователя на себя, и $SHELL указывает оболочку, которую следует использовать.

Подвести итоги:

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

Использование "exec" означает заменить существующую оболочку новой оболочкой, запущенной командой newgrp (поэтому выход из новой оболочки завершит работу).

Финал newgrp - необходим для восстановления обычной основной группы, поэтому файлы, которые вы создадите позже, будут иметь их в качестве владельца группы.

Примечание. Первоначальный вопрос автора заключался в том, как сделать добавленные группы видимыми в существующих процессах. gpasswd а также usermod команды не влияют на существующие процессы; вновь добавленные (или удаленные!) группы появляются в вашей учетной записи (исчезают из нее), то есть в файлах /etc/group и /etc/gshadow, но разрешения для существующих процессов не изменяются. Чтобы удалить разрешения, вы должны убить все запущенные процессы; newgrp - не будет перечитывать /etc/group и сбрасывать список групп; вместо этого он, кажется, просто использует группы, ранее связанные с процессом.

Чтобы возродить терминал, но сохранить работу приложений с графическим интерфейсом, попробуйте exec su -p $USER. Это сохраняет переменные среды (включая материал Xorg), но перезагружает группы.

В качестве альтернативы удалить exec для создания подоболочки вместо замены текущей оболочки.

Уже есть много правильных ответов, но это отлично сработало для меня в системах на основе Debian:

sudo -s -u ${USER}

Эта команда выполнит свою работу в среде sudo.

В -sflag запустить оболочку, как настроено в файле /etc/passwd.

Это делает трюк, если у вас есть sudo и это может спасти вас от ввода пароля еще раз в некоторых случаях:

sudo su $USER

Я не мог заставить команду 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

Принятый ответ правильный, но он подходит только для интерактивной оболочки и не работает в скриптах. Чтобы решить эту проблему, я использовал это:

newgrp <GroupName> << END
my_command
END

Это откроет новый сеанс с обновленными группами, запустит команду, а затем вернет вас к первому сеансу, в котором вы все еще не в группе. Это позволит вам создать группу и использовать ее в одном скрипте.

У меня была похожая проблема, но также и для не авторизованных пользователей. Перезапуск nscd не помог, но выполнение этой команды сделало: nscd -i group, Это должно дать команду nscd (демону кэширования) перезагрузить файл groups.

Мне нужно было сделать это в сценарии оболочки (сценарий добавляет текущего пользователя в группу, запускает более поздние команды, требующие членства в этой группе). newgrp Команда хрупкая в том смысле, что она может запускать только новую оболочку, а не произвольную команду (я хочу перезапустить текущий сценарий оболочки с оригинальными аргументами командной строки).

Вот мое решение, в котором используется много вариантов: (обратите внимание, что окружающему скрипту нужна какая-то ветвь, чтобы запустить эту функцию, только если требуемая группа в данный момент не активна):

(примечание: скрипт подразумевает, что 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"
}
Другие вопросы по тегам