Encontrando usuários duplicados no CentOS

4

Estou usando o código a seguir para encontrar o nome de usuário duplicado. No entanto, dá um erro.

#!/bin/bash
cat /etc/passwd | cut -f1 -d":" | /bin/sort -n | /usr/bin/uniq -c |\
    while read x; do [ -z "${x}" ] && break set - $x
        if [ $1 -gt 1 ]; then
            uids='/bin/gawk -F: '($1 == n) { print $3 }' n=$2 \
            /etc/passwd | xargs'
            echo "Duplicate User Name ($2): ${uids}"
        fi
    done

Estou enfrentando um erro de sintaxe próximo ao token 'concluído' e erro numérico. Como posso corrigir esse erro?

    
por jacqueline fernandez 31.07.2016 / 10:48

4 respostas

7
$ cut -d: -f1 /etc/passwd | sort | uniq -d

Isso irá extrair o primeiro campo (os nomes de usuários) do arquivo : -delimited /etc/passwd , classificar o resultado e reportar quaisquer duplicatas.

Para obter também o UID e o restante das entradas passwd duplicadas:

cut -d: -f1 /etc/passwd | sort | uniq -d |
while read -r username; do
  grep "^$username:" /etc/passwd
done

Para obter apenas os nomes de usuário duplicados e seu UID:

cut -d: -f1 /etc/passwd | sort | uniq -d |
while read -r username; do
  awk -F: -vu="$username" '$1 == u { print $1, $3 }' /etc/passwd
done

Uma breve nota sobre seu roteiro. A sintaxe parece basicamente ok, mas você precisa de ; após break e há um espaço após \ (isso pode ser um erro de recortar e colar (agora removido por uma edição) )). Além disso, eu evitaria dar caminhos completos para os utilitários padrão se não houver uma boa razão para isso, e o programa awk não exigirá o GNU awk , então apenas awk fará.

    
por 31.07.2016 / 11:39
7
  1. Você precisa ter um do em algum lugar entre o while e o done - normalmente, logo após o read , ou após a verificação de que você obteve dados.
  2. set - $x deve estar em uma linha sozinho ou pelo menos separado do break com um ponto e vírgula ( ; ). (Este é provavelmente um bom lugar para colocar o do .)

Sugestões:

  1. Em vez de fazer set - $x , considere alterar read x para read count name .
  2. Apenas para esclarecer, talvez você queira alterar '…' para $(…) - veja este , this , e este .
por 31.07.2016 / 11:26
3

Eu faria algo assim com o awk (one-liner):

awk -F: '{if ($1 in users) print "Duplicate Username: "$1 ; else users[$1]}' /etc/passwd

encontre o nome de usuário na variável de array de usuários, se duplicar msg mais adicione o usuário ao array

    
por 31.07.2016 / 11:42
0

Inspirado por resposta da ebal , este comando único awk replica a funcionalidade pretendida do script do OP:

awk -F: '{ uids[$1] = uids[$1] " " $3; }
         END { for (u in uids) { if (uids[u] ~ /. /)
                         print "Duplicate User Name (" u "):" uids[u]; } }'

Como na resposta da ebal, cria um array associativo, com uma entrada para cada nome de usuário exclusivo. Define o valor de cada entrada para a concatenação de um espaço e o UID para cada linha para o usuário. Então, depois de ler o arquivo inteiro, ele percorre os nomes de usuário exclusivos e verifica se ocorre mais de uma vez - reconhecido pelo fato de que a lista UID tem um espaço como diferente do primeiro caractere - e relata a informação desejada.

Isso se comportará de maneira estranha se os UIDs no arquivo contiverem espaços.

    
por 02.08.2016 / 03:11