Перезагрузите назначения группы пользователей 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.
В
-s
flag запустить оболочку, как настроено в файле /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"
}