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

348

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

# usermod -G <grouplist> <user>

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

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

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

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

Саймон
источник
Я знаю, что, по крайней мере, для некоторых менеджеров окон / сессий это можно сделать так, чтобы сессия подбирала новую группу и была доступна для любых новых процессов, запущенных из меню, кнопок панели или чего-либо еще. Я пришел сюда только сейчас, чтобы найти это снова, поэтому сейчас не могу сказать, как это сделать, и это, вероятно, характерно для оконного менеджера.
mc0e

Ответы:

205

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

id -g

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

newgrp <new group name>

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

newgrp <orig_group>

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

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

Редактировать: Это не требует от вас ввести пароль, что suбудет.

Legooolas
источник
6
Хороший трюк, мне это нравится
Саймон
1
На федоре я должен был сделать newgrp $USERвместо newgrp <orig_group>. Это означает, что мне не нужно было искать свой исходный идентификатор основной группы, так что это даже проще, чем это решение.
Ричард Тернер
2
Я обнаружил, что этого достаточно newgrp <new group name>. Это была Ubuntu 14.04
Эдвард Фальк,
4
@ EdwardFalk верно, но вы не хотите (не можете) оставить эту группу в качестве своей основной ...
mimoralea
4
Обратите внимание, что каждый из них newgrpсоздает новую оболочку, поэтому, когда вам нужно полностью выйти из сеанса, вам нужно выполнить «exit exit exit», чтобы пройти весь путь (:
jwd
371

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

su - $USER

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

id
stivlo
источник
3
Я думаю, что это лучший подход во многих случаях, но оригинальный постер действительно хотел обновить несколько оболочек в течение сеанса экрана. Это решение должно быть сделано из каждой оболочки.
Адриан Ратнапала
3
Хороший трюк, отлично работает!
genpfault
4
Исходное решение также исправит только один сеанс оболочки на экране. Я только что проверил это. Причина, по которой это решение работает, заключается в том, что вы порождаете новый сеанс, а не наследуете от исходной среды.
Дрор
4
Это действительно должен быть принятый ответ. Хороший трюк, спасибо!
Dotancohen
2
Это требует от вас ввести пароль, который может быть неудобным / нежелательным, если вы пытаетесь сделать это во многих сеансах.
Legooolas
156

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

exec su -l $USER

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

jhaagsma
источник
14
+1 за то, что не вложил пользователя в подоболочку; вы можете выйти / выйти как обычно с этим. Кроме того, если NOPASSWD: установлен в / etc / sudoers, вы можете вместо этого использовать его, exec sudo su -l $USERчтобы избежать запроса пароля.
Иван Икс
21
Имейте в виду: вас попросят ввести пароль sudo. Если вы ошиблись, ваш терминал закроется.
Тайлер Коллиер
1
@TylerCollier Иван сделал упоминаниеNOPASSWD:
pepoluan
32

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запустить в сеансе Screen, и ^ M, чтобы заставить Screen нажать «enter» в конце вашей команды.

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

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

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

screen -S <session_name> -p 0 -X stuff "exec sg <new_group_name> newgrp \`id -gn\`^M"
Патрик Конхи
источник
Отличный лайнер, который, похоже, не имеет других побочных эффектов, спасибо!
Кирилл Дюшон-Дорис
17

Использование newgrpкоманды решило проблему для меня:

newgrp <GroupName>

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

Паван Вегируту
источник
12

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

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

Mister_Tom
источник
По правде говоря, я почти уверен, что это не так - я нашел способ сделать это раньше на Linux-коробке. Однако на всю жизнь я не могу вспомнить, что это была за команда. Если я найду это, я отправлю это. Редактировать: только что нашел, я публикую это как ответ.
lunchmeat317
1
Спасибо за указание на это, это также мое понимание. Любой другой ответ здесь просто открывает новую оболочку, независимо от того, заменяет ли она одну открытую оболочку или перезапускает экран или что-то еще. Не существует волшебной панацеи для выдачи команды или сценария, чтобы каждый текущий сеанс, включая ваш сеанс X, отражал членство в новых группах.
Scravy
12

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

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

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

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

Удачи вам.

lunchmeat317
источник
11
попробовал xterm в X сессии, но это не сработало
dwery
3
попробовал на сеансе в tmux и там тоже ничего не получилось
Michael
2
Пробовал на Amazon linux 2, не получилось
Кирилл Дюшон-Дорис,
1
newgrp -запускает новый процесс оболочки
Piotr Findeisen
В свете вашего комментария к ответу Mister_Tom, это, как и все остальные ответы, обходной путь. Ответ Mister_Tom по-прежнему правильный.
Бродяга
4

Обобщить:

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

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

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

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

jimav
источник
Кстати, exec su - <username>может использоваться для получения новой оболочки входа в систему с установленными группами, но это не будет работать в сценариях, потому что новая оболочка будет считывать команды из терминала. Вы можете использовать его su -c "command ..." <myusername>для перезапуска сценария, но в результате в результате процесса не будет управляющего терминала, поэтому при попытке создания экранного редактора или другой интерактивной команды произойдет ошибка.
Джимав
Почему это было отвергнуто? Может кто-нибудь объяснить, что в этом плохого, потому что это было то, что пришло мне в голову, и я думаю, что мне это нравится больше всего?
jasonmp85
Ха, я проголосовал перед тестированием. newgrp -никак не заменит «основную группу». Ответ Патрика Конхеди здесь лучший, так как он не разветвляет и не меняет основную группу.
jasonmp85
1

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

Marki555
источник
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
snuggles08
источник
0

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

sudo su $USER
guaka
источник