2013-02-11 6 views
89

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

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

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

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

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

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

UPDATE:

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

getent passwd $user > /dev/null 

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

+0

Я думаю, что когда вы используете '$?' Вы получите код возврата 'test' команды. См. Ответ ниже. – user000001

+0

Это точный * код, который вы используете? Нет откликов «отголоски» между вызовом 'getent' и вашим оператором' if'? Это вызовет '$?', Чтобы проверить статус выхода 'echo', а не ваш вызов' getent'. – chepner

+2

Да, я думаю, вы имеете в виду '2> & 1' вместо' 2 &> 1'. –

ответ

21

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

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

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

+6

Это не работает, если сервер использует другую систему для управления такими приложениями, как NIS или LDAP. В этом случае вы можете использовать 'getent passwd | grep -c '^ имя пользователя:' ' –

0

В зависимости от реализации вашей оболочки (например, 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 
+0

изменение' $? 'дает мне тот же результат. Это версия bash: 'GNU bash, версия 4.1.5 (1) -release (i486-pc-linux-gnu)' – slayedbylucifer

+0

Попробуйте 'if test '$ RES" == "0"; то ... ' –

+0

' $? 'будет расширен до' ['работает, так что это не проблема. – chepner

178

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

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

+3

Вот что я использую. См. Http://superuser.com/questions/336275/find-out-if-user-name-exists – guettli

+6

отличный ответ - просто небольшая настройка, которая хорошо работает ... user_exists = $ (id -u user>/dev/null 2> & 1; echo $?) user_exists = 0, если «пользователь» существует, или 1, если не – Pancho

+1

Это сработало отлично! – normalUser

17

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

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

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

11

Это то, что я в конечном итоге делает в сценарии запуска в Freeswitch Баш:

# 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 " [email protected]:~# adduser --home /usr/local/freeswitch/ --shell /bin/false --no-create-home --ingroup daemon --disabled-password --disabled-login $FS_USER" 
    echo " ..." 
    echo " [email protected]:~# chown freeswitch:daemon /usr/local/freeswitch/ -R" 
    exit 1 
fi 
1

На самом деле я не могу воспроизвести проблему. Сценарий, написанный в вопросе, отлично работает, за исключением случая, когда $ 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 может не быть такой хорошей идеей. Когда все пойдет не так, вы не поймете, почему.

0

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

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

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

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

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

+0

Согласно http://superuser.com/questions/336275/find-out-if-user-name-exists –

1

Вход на сервер. grep "username"/etc/passwd При этом отобразится информация о пользователе, если таковая имеется.

1

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

sudo apt-get finger 
    finger "$username" 
Смежные вопросы