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

Recarregar as atribuições de grupo de um utilizador Linux sem sair do sistema

Quando se atribui a lista de grupos secundários de um utilizador usando:

# usermod -G <grouplist> <user>

é possível forçar esta atribuição de grupo a ter efeito sem sair de todas as sessões em execução?

Isto seria muito útil na situação em que existe uma sessão Screen com muitas shells em execução, uma vez que a sessão inteira precisa essencialmente de ser destruída para que a atribuição de grupo tenha efeito.

Penso que posso alterar o grupo primário do utilizador numa shell em execução usando o comando newgrp - existe alguma alternativa que funcione para grupos secundários?

Idealmente, eu quereria algo que tivesse efeito em cada shell sem ser executado manualmente em cada uma, mas se isso falhar, talvez alguma forma de forçar o Screen a executar o mesmo comando em cada uma.

Respostas (12)

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

A partir de dentro de uma shell, pode emitir o seguinte comando

su - $USER

id irá agora listar o novo grupo:

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

Horrivelmente hacky, mas poderia usar duas camadas de newgrp para conseguir isto para um grupo em particular:

id -g

…dar-lhe-á o actual ID do grupo primário. Chamamos a isto orig_group para os fins deste exemplo. Depois:

newgrp <new group name>

…irá mudá-lo para esse grupo como primário e adicioná-lo à lista de grupos devolvidos por groups ou id -G. Agora, mais um:

newgrp <orig_group>

…irá obter uma concha na qual poderá ver o novo grupo e o primário é o grupo original.

Isto é horrível e irá obter apenas um grupo adicionado de cada vez, mas ajudou-me um par de vezes a obter grupos adicionados sem sair da minha sessão X inteira (e. g. para que o fusível seja adicionado como grupo a um utilizador para que o sshfs funcione).

Editar : Isto também não requer que digite a sua palavra-passe, o que su irá.

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

Este truque elegante de este link funciona muito bem!

exec su -l $USER

Pensei em publicá-lo aqui pois sempre que me esqueço de como fazer isto, este é o primeiro link que aparece no google.

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

1. Obter uma shell com o novo grupo sem sair e entrar novamente

Se está a adicionar apenas um grupo, usei o seguinte:

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

Esta é uma variação do truque do newgrp de duas camadas do Legooolas, mas está numa linha e não requer que entre manualmente no seu grupo primário.

sg é newgrp mas aceita um comando para executar com o novo ID do grupo. O exec significa que o novo shell substitui o shell existente, por isso não precisa de “sair” duas vezes.

Ao contrário de usar o su, não precisa de digitar a sua palavra-passe. Também não actualiza o seu ambiente (para além de adicionar o grupo), por isso mantém o seu directório de trabalho actual, etc.

2. Executando o comando em todas as janelas Screen numa sessão

O comando at em Screen executa um comando em qualquer janela que especificar (note que isto é um comando Screen, não um comando shell).

Pode usar o seguinte comando para enviar o comando para todas as sessões existentes no Ecrã:

screen -S <session_name> -X at \# stuff "exec sg <new_group_name> newgrp ### 1. Obter uma shell com o novo grupo sem sair e entrar novamente 


Se está a adicionar apenas um grupo, usei o seguinte: 


exec sg newgrp id -gn “`

Esta é uma variação do truque do newgrp de duas camadas do Legooolas, mas está numa linha e não requer que entre manualmente no seu grupo primário.

id é newgrp mas aceita um comando para executar com o novo ID do grupo. O stuff significa que o novo shell substitui o shell existente, por isso não precisa de "sair” duas vezes.

Ao contrário de usar o su, não precisa de digitar a sua palavra-passe. Também não actualiza o seu ambiente (para além de adicionar o grupo), por isso mantém o seu directório de trabalho actual, etc.

2. Executando o comando em todas as janelas Screen numa sessão

O comando &007 em Screen executa um comando em qualquer janela que especificar (note que isto é um comando Screen, não um comando shell).

Pode usar o seguinte comando para enviar o comando para todas as sessões existentes no Ecrã:

id -gn### 1. Obter uma shell com o novo grupo sem sair e entrar novamente

Se está a adicionar apenas um grupo, usei o seguinte:

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

Esta é uma variação do truque do newgrp de duas camadas do Legooolas, mas está numa linha e não requer que entre manualmente no seu grupo primário.

&007 é newgrp mas aceita um comando para executar com o novo ID do grupo. O &007 significa que o novo shell substitui o shell existente, por isso não precisa de “sair” duas vezes.

Ao contrário de usar o su, não precisa de digitar a sua palavra-passe. Também não actualiza o seu ambiente (para além de adicionar o grupo), por isso mantém o seu directório de trabalho actual, etc.

2. Executando o comando em todas as janelas Screen numa sessão

O comando [ &007 ]&003 em Screen executa um comando em qualquer janela que especificar (note que isto é um comando Screen, não um comando shell).

Pode usar o seguinte comando para enviar o comando para todas as sessões existentes no Ecrã:

^M" “`

Note a necessidade de escapar aos backticks para obter o &007 para correr na sessão do Ecrã, e o ^M para obter o Ecrã para carregar em ‘enter’ no final do seu comando.

Note também que o comando [ &007 ]&003 do Ecrã simplesmente digita o texto do comando em seu nome. Portanto algo estranho pode acontecer se uma das janelas do ecrã tiver um comando semi-escrito num prompt de comando ou estiver a correr uma aplicação que não seja uma shell (e.g. emacs, top). Se isto for um problema, tenho algumas ideias:

  • Para se livrar de qualquer comando semi-escrito, pode adicionar ”^C" ao início do comando.
  • Para evitar correr o comando numa janela emacs, etc., pode pedir ao `at’ para filtrar no título da janela, etc. (no exemplo acima, eu uso “#”, que corresponde a todas as janelas, mas pode filtrar por título de janela, utilizador, etc.)

Para correr o comando numa janela específica (identificada pelo número da janela), use o seguinte:

screen -S <session_name> -p 0 -X stuff "exec sg <new_group_name> newgrp ### 1. Obter uma shell com o novo grupo sem sair e entrar novamente 


Se está a adicionar apenas um grupo, usei o seguinte: 


exec sg newgrp id -gn “`

Esta é uma variação do truque do newgrp de duas camadas do Legooolas, mas está numa linha e não requer que entre manualmente no seu grupo primário.

&007 é newgrp mas aceita um comando para executar com o novo ID do grupo. O &007 significa que o novo shell substitui o shell existente, por isso não precisa de "sair” duas vezes.

Ao contrário de usar o su, não precisa de digitar a sua palavra-passe. Também não actualiza o seu ambiente (para além de adicionar o grupo), por isso mantém o seu directório de trabalho actual, etc.

2. Executando o comando em todas as janelas Screen numa sessão

O comando [ &007 ]&003 em Screen executa um comando em qualquer janela que especificar (note que isto é um comando Screen, não um comando shell).

Pode usar o seguinte comando para enviar o comando para todas as sessões existentes no Ecrã:

screen -S <session_name> -X at \# stuff "exec sg <new_group_name> newgrp ### 1. Obter uma shell com o novo grupo sem sair e entrar novamente 


Se está a adicionar apenas um grupo, usei o seguinte: 


exec sg newgrp id -gn “`

Esta é uma variação do truque do newgrp de duas camadas do Legooolas, mas está numa linha e não requer que entre manualmente no seu grupo primário.

&007 é newgrp mas aceita um comando para executar com o novo ID do grupo. O &007 significa que o novo shell substitui o shell existente, por isso não precisa de "sair” duas vezes.

Ao contrário de usar o su, não precisa de digitar a sua palavra-passe. Também não actualiza o seu ambiente (para além de adicionar o grupo), por isso mantém o seu directório de trabalho actual, etc.

2. Executando o comando em todas as janelas Screen numa sessão

O comando [ &007 ]&003 em Screen executa um comando em qualquer janela que especificar (note que isto é um comando Screen, não um comando shell).

Pode usar o seguinte comando para enviar o comando para todas as sessões existentes no Ecrã:

id -gn### 1. Obter uma shell com o novo grupo sem sair e entrar novamente

Se está a adicionar apenas um grupo, usei o seguinte:

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

Esta é uma variação do truque do newgrp de duas camadas do Legooolas, mas está numa linha e não requer que entre manualmente no seu grupo primário.

&007 é newgrp mas aceita um comando para executar com o novo ID do grupo. O &007 significa que o novo shell substitui o shell existente, por isso não precisa de “sair” duas vezes.

Ao contrário de usar o su, não precisa de digitar a sua palavra-passe. Também não actualiza o seu ambiente (para além de adicionar o grupo), por isso mantém o seu directório de trabalho actual, etc.

2. Executando o comando em todas as janelas Screen numa sessão

O comando [ &007 ]&003 em Screen executa um comando em qualquer janela que especificar (note que isto é um comando Screen, não um comando shell).

Pode usar o seguinte comando para enviar o comando para todas as sessões existentes no Ecrã:

^M" “`

Note a necessidade de escapar aos backticks para obter o &007 para correr na sessão do Ecrã, e o ^M para obter o Ecrã para carregar em ‘enter’ no final do seu comando.

Note também que o comando [ &007 ]&003 do Ecrã simplesmente digita o texto do comando em seu nome. Portanto algo estranho pode acontecer se uma das janelas do ecrã tiver um comando semi-escrito num prompt de comando ou estiver a correr uma aplicação que não seja uma shell (e.g. emacs, top). Se isto for um problema, tenho algumas ideias:

  • Para se livrar de qualquer comando semi-escrito, pode adicionar ”^C" ao início do comando.
  • Para evitar correr o comando numa janela emacs, etc., pode pedir ao `at’ para filtrar no título da janela, etc. (no exemplo acima, eu uso “#”, que corresponde a todas as janelas, mas pode filtrar por título de janela, utilizador, etc.)

Para correr o comando numa janela específica (identificada pelo número da janela), use o seguinte:

id -gn### 1. Obter uma shell com o novo grupo sem sair e entrar novamente

Se está a adicionar apenas um grupo, usei o seguinte:

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

Esta é uma variação do truque do newgrp de duas camadas do Legooolas, mas está numa linha e não requer que entre manualmente no seu grupo primário.

&007 é newgrp mas aceita um comando para executar com o novo ID do grupo. O &007 significa que o novo shell substitui o shell existente, por isso não precisa de “sair” duas vezes.

Ao contrário de usar o su, não precisa de digitar a sua palavra-passe. Também não actualiza o seu ambiente (para além de adicionar o grupo), por isso mantém o seu directório de trabalho actual, etc.

2. Executando o comando em todas as janelas Screen numa sessão

O comando [ &007 ]&003 em Screen executa um comando em qualquer janela que especificar (note que isto é um comando Screen, não um comando shell).

Pode usar o seguinte comando para enviar o comando para todas as sessões existentes no Ecrã:

screen -S <session_name> -X at \# stuff "exec sg <new_group_name> newgrp ### 1. Obter uma shell com o novo grupo sem sair e entrar novamente 


Se está a adicionar apenas um grupo, usei o seguinte: 


exec sg newgrp id -gn “`

Esta é uma variação do truque do newgrp de duas camadas do Legooolas, mas está numa linha e não requer que entre manualmente no seu grupo primário.

&007 é newgrp mas aceita um comando para executar com o novo ID do grupo. O &007 significa que o novo shell substitui o shell existente, por isso não precisa de "sair” duas vezes.

Ao contrário de usar o su, não precisa de digitar a sua palavra-passe. Também não actualiza o seu ambiente (para além de adicionar o grupo), por isso mantém o seu directório de trabalho actual, etc.

2. Executando o comando em todas as janelas Screen numa sessão

O comando [ &007 ]&003 em Screen executa um comando em qualquer janela que especificar (note que isto é um comando Screen, não um comando shell).

Pode usar o seguinte comando para enviar o comando para todas as sessões existentes no Ecrã:

id -gn### 1. Obter uma shell com o novo grupo sem sair e entrar novamente

Se está a adicionar apenas um grupo, usei o seguinte:

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

Esta é uma variação do truque do newgrp de duas camadas do Legooolas, mas está numa linha e não requer que entre manualmente no seu grupo primário.

&007 é newgrp mas aceita um comando para executar com o novo ID do grupo. O &007 significa que o novo shell substitui o shell existente, por isso não precisa de “sair” duas vezes.

Ao contrário de usar o su, não precisa de digitar a sua palavra-passe. Também não actualiza o seu ambiente (para além de adicionar o grupo), por isso mantém o seu directório de trabalho actual, etc.

2. Executando o comando em todas as janelas Screen numa sessão

O comando [ &007 ]&003 em Screen executa um comando em qualquer janela que especificar (note que isto é um comando Screen, não um comando shell).

Pode usar o seguinte comando para enviar o comando para todas as sessões existentes no Ecrã:

^M" “`

Note a necessidade de escapar aos backticks para obter o &007 para correr na sessão do Ecrã, e o ^M para obter o Ecrã para carregar em ‘enter’ no final do seu comando.

Note também que o comando [ &007 ]&003 do Ecrã simplesmente digita o texto do comando em seu nome. Portanto algo estranho pode acontecer se uma das janelas do ecrã tiver um comando semi-escrito num prompt de comando ou estiver a correr uma aplicação que não seja uma shell (e.g. emacs, top). Se isto for um problema, tenho algumas ideias:

  • Para se livrar de qualquer comando semi-escrito, pode adicionar ”^C" ao início do comando.
  • Para evitar correr o comando numa janela emacs, etc., pode pedir ao `at’ para filtrar no título da janela, etc. (no exemplo acima, eu uso “#”, que corresponde a todas as janelas, mas pode filtrar por título de janela, utilizador, etc.)

Para correr o comando numa janela específica (identificada pelo número da janela), use o seguinte:

^M" “`

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

Usando o comando newgrp resolveu o problema para mim:

newgrp <GroupName>

Este post no blog tem uma explicação detalhada.

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

Pode fazer isto.

Adicione quantos grupos quiser usando usermod -G. Depois, como utilizador com uma sessão em execução, execute newgrp - apenas com o argumento ‘-’.

Isto reinicia o id do grupo para o padrão, mas também irá definir os grupos secundários. Pode verificar isto executando o groups a partir da sessão actual, antes e depois do usermod e do newgrp.

Isto tem de ser executado a partir de cada sessão aberta - não sei muito sobre o ecrã. No entanto, se for possível iterar em todas as sessões abertas e correr o newgrp, deve ser bom. Não terá de se preocupar em conhecer os grupos ou as IDs dos grupos.

A melhor das sortes para si.

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

Os grupos são normalmente numerados no login, não há maneira de forçá-los a fazer novamente a contagem do grupo sem sair e entrar novamente.

Muitas respostas votadas aqui parecem usar uma alternativa que invoca uma nova shell com ambiente novo (o mesmo que entrar novamente). a shell pai e todos os outros programas em execução contínua geralmente não receberão a nova associação do grupo até serem novamente convocados a partir de uma nova shell normalmente após o logout e login limpos.

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

Para resumir:

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

Usar ‘exec’ significa substituir a shell existente pela nova shell iniciada pelo comando newgrp (portanto, sair da nova shell faz o logout).

O newgrp - final é necessário para restaurar o seu grupo primário normal, portanto, os ficheiros que criar mais tarde terão isso como proprietário do grupo.

Nota: A questão do cartaz original era como tornar os grupos recém-adicionados visíveis nos processos existentes. Os comandos gpasswd e usermod não afectam os processos existentes; os grupos recentemente adicionados (ou eliminados!) aparecem (desaparecem) na sua conta, ou seja, nos ficheiros /etc/group e /etc/gshadow, mas as permissões para os processos existentes não são alteradas. Para remove permissões você tem que matar qualquer processo em execução; newgrp - não irá reler /etc/group e reiniciar a lista de grupos; em vez disso, parece que apenas usa os grupos anteriormente associados ao processo.

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

Não consegui pôr o comando do newgrp a funcionar. Não tenho a certeza se isto depende do /etc/sudoers, mas normalmente tenho de digitar a minha password para o sudo, e isto funcionou sem requerer a minha password:

[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

Isto faz o truque se tiver sudo e pode salvá-lo de introduzir a sua senha mais uma vez em alguns casos:

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

Eu precisava fazer isso em um script da shell (o script adiciona o usuário atual a um grupo, executa comandos posteriores que exigem essa adesão ao grupo). O comando newgrp é frágil na medida em que só pode correr uma nova shell em vez de um comando arbitrário (quero voltar a correr o actual script shell com args originais da linha de comandos).

Aqui está a minha solução, que usa muitos bash-isms: (note que o script circundante só precisa de algum tipo de ramo para correr esta função se o grupo requerido não estiver actualmente activo):

(nota: o script implica que correu sudo adduser $user docker, o que significa que também poderia correr sudo docker em todo o lado em vez de docker mas isso era indesejável neste caso)

# 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

Tive um problema semelhante, mas também para os utilizadores não ligados à Internet. O reinício do nscd não ajudou, mas a execução deste comando ajudou: nscd -i group. Isto deve instruir o nscd (caching daemon) a recarregar o ficheiro de grupos.