Проверьте, существует ли пользователь

165

Я хочу создать скрипт, чтобы проверить, существует ли пользователь. Я использую логику ниже:

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

Таким образом, если пользователь существует, то у нас есть успех, иначе пользователь не существует. Я поставил выше команду в скрипте bash, как показано ниже:

#!/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

Теперь мой сценарий всегда говорит, что пользователь существует независимо от того, что:

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

Почему вышеуказанное условие всегда оценивается как ИСТИНА и говорит, что пользователь существует?

Куда я иду не так?

ОБНОВИТЬ:

Прочитав все ответы, я обнаружил проблему в своем сценарии. Проблема была в том, как я перенаправлял getentвывод. Таким образом, я удалил все вещи перенаправления и сделал getentстроку такой:

getent passwd $user  > /dev/null

Теперь мой скрипт работает нормально.

slayedbylucifer
источник
Я думаю, что при использовании $?вы получите код возврата testкоманды. Смотрите ответ ниже.
user000001
Разве что точный код , который вы работаете? Нет "эхо" операторов отладки между вызовом getentи вашим ifоператором? Это может привести $?к проверке состояния выхода echo, а не вашего вызова getent.
chepner
4
Да, я думаю, что ты имеешь в виду 2>&1вместо 2&>1.
Тим Людвински
Код работает с непустым вводом, но если $1он не установлен, оператор if вернет true. Из моего тестирования, решение было бы обернуть $1в двойных кавычках: getent passwd "$1" > /dev/null 2&>1.
Винс
Пожалуйста, отметьте ответ
Efren

Ответы:

292

Вы также можете проверить пользователя по idкоманде.

id -u nameдает вам идентификатор этого пользователя. если пользователь не существует, вы получаете команду, возвращающую значение ( $?)1

Кент
источник
3
Это то, что я использую. См superuser.com/questions/336275/find-out-if-user-name-exists
guettli
24
отличный ответ - просто небольшая настройка, которая работает хорошо ... user_exists = $ (id -u user> / dev / null 2> & 1; echo $?) user_exists = 0, если "user" существует, или 1, если нет
Pancho
5
@Pancho Я думаю, что ваша переменная должна называться user_doesnt_exist
Уилл Шеппард
1
@WillSheppard: На общем уровне логическая обработка в bash, на мой взгляд, не совсем ясна, и я обычно избегаю неявных логических выводов в моем коде. Следующие материалы интересны для чтения и интересны, поскольку они предпочитают 0 = true и <not 0> = false для целей bash и, хотя не фактически, выровняются с именем переменной, которое я использовал также с логической точки зрения: stackoverflow.com/a/5431932 / 3051627 . stackoverflow.com/questions/2933843/… .
Панчо
2
Благодаря комментарию @ Pancho я смог добиться этого, просто отправив ошибку в void и сделав это validuser(){ [[ -n $(id -u "$1" 2>/dev/null) ]] && echo 1 || echo 0; }. Это в значительной степени возвращает 1, если пользователь существует, или 0, если его нет.
lu1s
32

Почему бы вам просто не использовать

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

Он вернет 1 (поскольку у пользователя есть макс. 1 запись), если пользователь существует, и 0, если его нет.

poitroae
источник
19
Это не работает, если сервер использует другую систему для управления такими приложениями, как NIS или LDAP. В этом случае вы можете использоватьgetent passwd | grep -c '^username:'
Тоби Джексон
1
это вернет 1, если у вас есть имя пользователя, скажем, «test1» и вы хотите создать новое имя пользователя с именем «test».
Марин Недея
2
@MarinNedea двоеточие :после имени пользователя защищает от сопоставления подстроки путем сопоставления с разделителем полей, поэтому описанный вами эффект не произойдет.
Стефан Гурихон
30

Нет необходимости явно проверять код выхода. Пытаться

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

Если это не сработает, значит, что-то не так с вами getent, или у вас определено больше пользователей, чем вы думаете.

chepner
источник
23

Это то, что я сделал в Freeswitchсценарии запуска 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
Даниэль Соколовский
источник
14

Я предлагаю использовать команду id, так как она проверяет правильность существования пользователя в отношении записи файла passwd, которая не обязательна, означает то же самое:

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

Примечание: 0 - это root uid.

Валдас Рапшявичюс
источник
12

Я использовал это таким образом:

if [ $(getent passwd $user) ] ; then
        echo user $user exists
else
        echo user $user doesn\'t exists
fi
Takeda
источник
9

Безусловно самое простое решение:

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

>/dev/null 2>&1Может быть сокращен до &>/dev/nullв Bash.

Fleshgrinder
источник
Да спасибо!
Зейн Хичкокс
7

Скрипт, чтобы проверить, существует ли пользователь Linux или нет

Скрипт Чтобы проверить, существует ли пользователь или нет

#! /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
Бакул Гупта
источник
2
Зачем использовать cat? grep $USER_NAME /etc/passwd >/dev/null 2>&1
Алекс Рош
Да, Алекс Рош, нет необходимости использовать кошку, я использую ее, чтобы иметь лучший способ визуализации концепции для начинающих.
Бакул Гупта
6

Поздний ответ, но fingerтакже показывает больше информации о пользователе

  sudo apt-get finger 
  finger "$username"
jackotonye
источник
OP может не использовать Debian.
Нарендра-Чоудхары
3

На самом деле я не могу воспроизвести проблему. Сценарий, как написано в вопросе, работает нормально, за исключением случая, когда $ 1 пусто.

Однако в скрипте есть проблема, связанная с перенаправлением stderr. Хотя эти две формы &>и >&существуют, в вашем случае вы хотите использовать >&. Вы уже перенаправлены stdout, поэтому форма &>не работает. Вы можете легко проверить это следующим образом:

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

Вы увидите файл с именем 1в текущем каталоге. Вы хотите использовать 2>&1вместо этого, или используйте это:

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

Это также перенаправляет stdoutи stderrк/dev/null .

Предупреждение Перенаправление stderrна /dev/nullне может быть такой хорошей идеей. Когда что-то пойдет не так, вы не поймете, почему.

Кристиан Худжер
источник
3

информация о пользователе хранится в / etc / passwd, поэтому вы можете использовать "grep 'usename' / etc / passwd", чтобы проверить, существует ли имя пользователя. тем временем вы можете использовать команду оболочки «id», она напечатает идентификатор пользователя и идентификатор группы, если пользователя не существует, она напечатает сообщение «нет такого пользователя».

Ю Чай
источник
2

Авторизуйтесь на сервере. grep "username" / etc / passwd Это покажет детали пользователя, если они есть.

сям
источник
3
Это также будет соответствовать любому имени пользователя, которое содержит «имя пользователя». Например, "some_username". Вы хотели бы сделатьif grep -q "^username:" /etc/passwd; then ...
maedox
2

Используя sed:

username="alice"
if [ `sed -n "/^$username/p" /etc/passwd` ]
then
    echo "User [$username] already exists"
else
    echo "User [$username] doesn't exist"
fi
Стив
источник
1

В зависимости от реализации вашей оболочки (например, Busybox или взрослый) [оператор может запустить процесс, изменив$? .

Пытаться

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
Евгений Рик
источник
изменение $?дает мне тот же результат. Это версия Bash:GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
Slayedbylucifer
Попробуйтеif test "$RES" == "0"; then ...
Eugen Rieck
1
$?будет расширен до [запуска, так что это не проблема.
chepner
1
Вместо того, чтобы проверять результат команды, вы можете проверить команду напрямую: 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

Ниже приведен скрипт для проверки распространения ОС и создания пользователя, если он не существует, и ничего не делать, если пользователь существует.

#!/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
Сантош Гароле
источник
0

Создать системного пользователя, some_userесли он не существует

if [[ $(getent passwd some_user) = "" ]]; then
    sudo adduser --no-create-home --force-badname --disabled-login --disabled-password --system some_user
fi
Лучаниновыми
источник
0

Мне нравится это хорошее решение в одну строку

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

и в сценарии:

#!/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

использовать:

[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
Нир Визел
источник