adicionando lista de usuários a vários grupos

2

Eu quero escrever um script de shell que adicionará uma lista de usuários, definidos em users.txt , a vários grupos existentes.

Por exemplo, eu tenho a , b , c , d , e , f , g usuários que serão adicionados aos grupos de acordo com o script e eu tenho p , q , r , s , t groups. Abaixo está a saída esperada de /etc/groups file:

p:x:10029:a,c,d
q:x:10030:b,c,f,g
r:x:10031:a,b,c,e
s:x:10032:c,g
t:x:10033:a,b,c,d,e

Então, como conseguir isso?

    
por Rahul 17.07.2014 / 09:02

3 respostas

5

A melhor e mais simples abordagem seria analisar um arquivo com as informações necessárias como sugerido por @DannyG . Embora seja assim que eu faria sozinho, outra seria codificar as combinações usuário / grupos no seu script. Por exemplo:

#!/usr/bin/env bash

## Set up an indexed array where the user is the key
## and the groups the values.
declare -A groups=(
    ["alice"]="groupA,groupB" 
    ["bob"]="groupA,groupC" 
    ["cathy"]="groupB,groupD"
)

## Now, go through each user (key) of the array,
## create the user and add them to the right groups.
for user in "${!groups[@]}"; do 
    useradd -U -G "${groups[$user]}" "$user" 
done

NOTA: O texto acima assume uma versão bash > = 4, uma vez que as matrizes associativas não estavam disponíveis em versões anteriores.

    
por 17.07.2014 / 13:12
5

Como nenhum exemplo de entrada é dado, vou assumir um padrão muito básico:

Uesrs groups
a p,r,t  
b p,q 

Nesse caso, você tem várias opções, porque usermod -G pode usar a segunda coluna nativamente.

algo como

while read line
do
    usermod -G "$(cut -f2 -d" ")" $(cut -f1 -d" ")
done < users.txt

O loop while lê cada linha do users.txt e passa para usermod.
o comando usermod -G group1,group2,group3 user altera os grupos do usuário para os grupos solicitados.
cut simplesmente separa os campos com base no delimitador -d " " , então o primeiro campo é usado como nome de usuário (nome de login) e o segundo campo é para os grupos. Se você deseja acrescentar os grupos aos grupos atuais (existentes) - adicione -a para que o comando se pareça com usermod -a -G ...

    
por 17.07.2014 / 10:35
3

Devido aos seus comentários, você pode simplesmente criar estaticamente o script com os grupos escritos nele. Este script espera uma lista de usuários, um usuário por linha, na entrada padrão. Então, chame-o com ./script < users.txt , por exemplo.

#!/bin/bash

groups="p q r" # the list of all groups you want your users in

# the following function is a case statement
# it takes as first argument a user, and as second argument a group
# it returns 0 if the user must be added to the group and 1 otherwise
must_belong_to() {
     case $2 in  # first we explore all the groups
     p)
          case $1 in  # and for each of them, we examine the users
          a | b )  # first selection: the users that must belong to the group
              true
          ;;
          *) # second selection: all the others
              false
          ;;
          esac
      q)
          # same here...
          ;;
      esac
  }

# we loop on the input file, to process one entry 
# (i.e. one user) at a time
while read user
do
    # We add the user. You may want to give some options here 
    # like home directory (-d), password (-p)...
    useradd $user 

    # then we loop on the existing groups to see in which 
    # one the user must be added
    for g in $groups  
    do
        # if the user must be added to the group $g
        if must_belong_to $user $g  
        then
             # we add it with the command gpasswd
             gpasswd -a $user $g 
        fi
    done
 done

Como explicado por @terdon, esta versão do must_belong_to() pode crescer rapidamente. Aqui está outra solução usando matrizes associativas:

#!/bin/bash
declare -A groups

# we declare all the groups and then, for each one, its members
all_the_groups="a b"
groups[a]="p q r"
groups[b]="q r s"

must_belong_to() {
    # we extract a list of all users for the group in parameter
    read -a all_the_users <<< "${groups["$2"]}"

    # we iterate over the users from the group
    for u in $all_the_users
    do
        # if the user belong to the group, 
        # we return here
        [[ $u == $1 ]] && return 0
    done

    # in case the user dosn't belong to the group,
    # we end up here
    return 1
}
    
por 17.07.2014 / 10:08