Verifique se existe um usuário

164

Quero criar um script para verificar se existe um usuário. Estou usando a lógica abaixo:

# getent passwd test > /dev/null 2&>1
# echo $?
0
# getent passwd test1 > /dev/null 2&>1
# echo $?
2

Portanto, se o usuário existe, temos sucesso, caso contrário, o usuário não existe. Eu coloquei o comando acima no script bash como abaixo:

#!/bin/bash

getent passwd $1 > /dev/null 2&>1

if [ $? -eq 0 ]; then
    echo "yes the user exists"
else
    echo "No, the user does not exist"
fi

Agora, meu script sempre diz que o usuário existe, não importa o que:

# sh passwd.sh test
yes the user exists
# sh passwd.sh test1
yes the user exists
# sh passwd.sh test2
yes the user exists

Por que a condição acima sempre avalia como VERDADEIRA e diz que o usuário existe?

Onde eu estou errando?

ATUALIZAR:

Depois de ler todas as respostas, encontrei o problema no meu script. O problema era o modo como eu estava redirecionando a getentsaída. Então eu removi todo o material de redirecionamento e fiz a getentlinha ficar assim:

getent passwd $user  > /dev/null

Agora meu script está funcionando bem.

slayedbylucifer
fonte
Eu acho que quando você usa $?você obtém o código de retorno do testcomando. Veja a resposta abaixo.
user000001
Esse é o código exato que você está executando? Nenhuma declaração de depuração "eco" entre a chamada getente a sua ifdeclaração? Isso causaria $?a verificação do status de saída echoe não da sua ligação getent.
chepner
4
Sim, eu acho que você quer dizer em 2>&1vez de 2&>1.
Tim Ludwinski
O código funciona com entrada não vazia, mas se $1não estiver definido, a instrução if retornará true. Do meu testes, solução seria para embrulhar $1entre aspas: getent passwd "$1" > /dev/null 2&>1.
Vince
Por favor, marque uma resposta
Efren

Respostas:

292

você também pode verificar o usuário por idcomando.

id -u namefornece o ID desse usuário. se o usuário não existir, você terá o comando return value ( $?)1

Kent
fonte
24
ótima resposta - apenas um pequeno ajuste que funciona bem ... user_exists = $ (id -u usuário> / dev / null 2> & 1; echo $?) user_exists = 0 se "user" existir ou 1 se não existir
Pancho
5
@Pancho Eu acho que a variável deve ser nomeado user_doesnt_exist
Will Sheppard
1
@WillSheppard: Em um nível geral, o tratamento booleano no bash é, na minha opinião, pouco claro e normalmente evito inferências booleanas implícitas no meu código. A seguir, é interessante ler e favorecer ambos 0 = true e <not 0> = false para fins do bash e, embora não seja de fato, alinhe-se com o nome da variável que usei de uma perspectiva booleana também: stackoverflow.com/a/5431932 / 3051627 . stackoverflow.com/questions/2933843/… .
Pancho
2
Graças ao comentário de @ Pancho, eu consegui isso, enviando o erro para o vazio e fazendo validuser(){ [[ -n $(id -u "$1" 2>/dev/null) ]] && echo 1 || echo 0; }. Isso retorna praticamente 1 se o usuário existir ou 0 se não existir.
lu1s 6/02
31

Por que você simplesmente não usa

grep -c '^username:' /etc/passwd

Ele retornará 1 (já que um usuário possui no máximo 1 entrada) se o usuário existir e 0 se não existir.

poitroae
fonte
19
Isso não funciona se o servidor estiver usando outro sistema para gerenciar usos como NIS ou LDAP. Nesse caso, você pode usargetent passwd | grep -c '^username:'
Toby Jackson
1
isso retornará 1 se você tiver um nome de usuário, digamos "test1" e desejar criar um novo nome de usuário chamado "test".
Marin Nedea
2
@MarinNedea os dois pontos :após o nome de usuário protegem contra a correspondência de substring combinando com o separador de campos, para que o efeito que você descreve não aconteça.
Stéphane Gourichon
30

Não há necessidade de verificar o código de saída explicitamente. Experimentar

if getent passwd $1 > /dev/null 2>&1; then
    echo "yes the user exists"
else
    echo "No, the user does not exist"
fi

Se isso não funcionar, há algo errado com o seu getent, ou você tem mais usuários definidos do que pensa.

chepner
fonte
23

Isto é o que acabei fazendo em um Freeswitchscript de inicialização do bash:

# Check if user exists
if ! id -u $FS_USER > /dev/null 2>&1; then
    echo "The user does not exist; execute below commands to crate and try again:"
    echo "  root@sh1:~# adduser --home /usr/local/freeswitch/ --shell /bin/false --no-create-home --ingroup daemon --disabled-password --disabled-login $FS_USER"
    echo "  ..."
    echo "  root@sh1:~# chown freeswitch:daemon /usr/local/freeswitch/ -R"
    exit 1
fi
Daniel Sokolowski
fonte
14

Sugiro usar o comando id, pois ele testa a entrada válida do arquivo wrt passwd da existência do usuário, o que não é necessário, significa o mesmo:

if [ `id -u $USER_TO_CHECK 2>/dev/null || echo -1` -ge 0 ]; then 
echo FOUND
fi

Nota: 0 é o usuário root.

Valdas Rapševičius
fonte
12

Eu estava usando dessa maneira:

if [ $(getent passwd $user) ] ; then
        echo user $user exists
else
        echo user $user doesn\'t exists
fi
Takeda
fonte
9

De longe a solução mais simples:

if id -u user >/dev/null 2>&1; then
    echo user exists
else
    echo user missing
fi

O >/dev/null 2>&1pode ser reduzido para &>/dev/nullno Bash.

Triturador de Carne
fonte
Sim obrigado!
Zane Hitchcox
7

Script para verificar se o usuário Linux existe ou não

Script Para verificar se o usuário existe ou não

#! /bin/bash
USER_NAME=bakul
cat /etc/passwd | grep ${USER_NAME} >/dev/null 2>&1
if [ $? -eq 0 ] ; then
    echo "User Exists"
else
    echo "User Not Found"
fi
Bakul Gupta
fonte
2
Por que usar cat? grep $USER_NAME /etc/passwd >/dev/null 2>&1
Alexx Roche
Sim Alexx Roche, não há necessidade de usar gato, tenho uso para ter uma maneira melhor de visualizar o conceito para iniciantes.
Bakul Gupta
6

Resposta tardia, mas fingertambém mostra mais informações sobre o usuário

  sudo apt-get finger 
  finger "$username"
jackotonye
fonte
O OP pode não estar usando o Debian.
narendra-choudhary 13/03
3

Na verdade, não posso reproduzir o problema. O script, conforme escrito na pergunta, funciona bem, exceto no caso em que $ 1 está vazio.

No entanto, há um problema no script relacionado ao redirecionamento de stderr. Embora as duas formas &>e >&existem, em seu caso, você quer usar >&. Você já redirecionou stdout, é por isso que o formulário &>não funciona. Você pode facilmente verificar desta maneira:

getent /etc/passwd username >/dev/null 2&>1
ls

Você verá um arquivo nomeado 1no diretório atual. Você deseja usar 2>&1, ou use o seguinte:

getent /etc/passwd username &>/dev/null

Isso também redireciona stdoute stderrpara /dev/null.

Aviso Redirecionar stderrpara /dev/nullpode não ser uma boa idéia. Quando as coisas dão errado, você não tem idéia do porquê.

Christian Hujer
fonte
3

as informações do usuário são armazenadas em / etc / passwd, para que você possa usar "grep 'nome de usuário' / etc / passwd" para verificar se o nome de usuário existe. Enquanto isso, você pode usar o comando shell "id", ele imprimirá a identificação do usuário e a identificação do grupo; se o usuário não existir, imprimirá a mensagem "sem esse usuário".

Yu Chai
fonte
2

Faça login no servidor. grep "nome de usuário" / etc / passwd Isso exibirá os detalhes do usuário, se presentes.

syam
fonte
3
Isso também corresponderá a qualquer nome de usuário que contenha "nome de usuário". Por exemplo, "some_username". Você gostaria de fazerif grep -q "^username:" /etc/passwd; then ...
maedox
2

Usando sed:

username="alice"
if [ `sed -n "/^$username/p" /etc/passwd` ]
then
    echo "User [$username] already exists"
else
    echo "User [$username] doesn't exist"
fi
Steve
fonte
1

Dependendo da implementação do seu shell (por exemplo, Busybox x adulto), o [operador pode iniciar um processo, mudando $?.

Experimentar

getent passwd $1 > /dev/null 2&>1
RES=$?

if [ $RES -eq 0 ]; then
    echo "yes the user exists"
else
    echo "No, the user does not exist"
fi
Eugen Rieck
fonte
mudar $?me dá a mesma saída. Esta é a versão do bash:GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
slayedbylucifer
Experimenteif test "$RES" == "0"; then ...
Eugen Rieck 11/02
1
$?seria expandido antes das [execuções, então isso não é um problema.
chepner
1
Em vez de testar o resultado do comando, você pode testá-lo diretamente: if getent passwd $1 > /dev/null 2&>1; then echo "yes the user exists" else echo "No, the user does not exist" fi
GMartinez
1

Abaixo está o script para verificar a distribuição do SO e criar Usuário, se não existir, e não fazer nada, se o usuário existir.

#!/bin/bash

# Detecting OS Ditribution
if [ -f /etc/os-release ]; then
    . /etc/os-release
    OS=$NAME
elif type lsb_release >/dev/null 2>&1; then
OS=$(lsb_release -si)
elif [ -f /etc/lsb-release ]; then
    . /etc/lsb-release
    OS=$DISTRIB_ID
else
    OS=$(uname -s)
fi

 echo "$OS"

 user=$(cat /etc/passwd | egrep -e ansible | awk -F ":" '{ print $1}')

 #Adding User based on The OS Distribution
 if [[ $OS = *"Red Hat"* ]] || [[ $OS = *"Amazon Linux"* ]] || [[ $OS = *"CentOS"*  
]] && [[ "$user" != "ansible" ]];then
 sudo useradd ansible

elif [ "$OS" =  Ubuntu ] && [ "$user" != "ansible" ]; then
sudo adduser --disabled-password --gecos "" ansible
else
  echo "$user is already exist on $OS"
 exit
fi
Santosh Garole
fonte
0

Crie usuário do sistema some_userse ele não existir

if [[ $(getent passwd some_user) = "" ]]; then
    sudo adduser --no-create-home --force-badname --disabled-login --disabled-password --system some_user
fi
luchaninov
fonte
0

Eu gosto dessa ótima solução de uma linha

getent passwd username > /dev/null 2&>1 && echo yes || echo no

e no script:

#!/bin/bash

if [ "$1" != "" ]; then
        getent passwd $1 > /dev/null 2&>1 && (echo yes; exit 0) || (echo no; exit 2)
else
        echo "missing username"
        exit -1
fi

usar:

[mrfish@yoda ~]$ ./u_exists.sh root
yes
[mrfish@yoda ~]$ echo $?
0

[mrfish@yoda ~]$ ./u_exists.sh
missing username
[mrfish@yoda ~]$ echo $?
255

[mrfish@yoda ~]$ ./u_exists.sh aaa
no
[mrfish@indegy ~]$ echo $?
2
nir vizel
fonte