Kiểm tra xem người dùng có tồn tại không


164

Tôi muốn tạo một tập lệnh để kiểm tra xem người dùng có tồn tại không. Tôi đang sử dụng logic dưới đây:

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

Vì vậy, nếu người dùng tồn tại, thì chúng ta đã thành công, người khác không tồn tại. Tôi đã đặt lệnh trên trong tập lệnh bash như dưới đây:

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

Bây giờ, tập lệnh của tôi luôn nói rằng người dùng tồn tại bất kể điều gì:

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

Tại sao điều kiện trên luôn luôn đánh giá là ĐÚNG và nói rằng người dùng tồn tại?

Tôi làm sai ở đâu?

CẬP NHẬT:

Sau khi đọc tất cả các phản hồi, tôi thấy vấn đề trong kịch bản của mình. Vấn đề là cách tôi chuyển hướng getentđầu ra. Vì vậy, tôi đã loại bỏ tất cả các công cụ chuyển hướng và làm cho getentdòng trông như thế này:

getent passwd $user  > /dev/null

Bây giờ kịch bản của tôi đang hoạt động tốt.


Tôi nghĩ rằng khi bạn sử dụng, $?bạn nhận được mã trả về của testlệnh. Xem câu trả lời dưới đây.
user000001

Đó có phải là mã chính xác mà bạn đang chạy không? Không có câu lệnh gỡ lỗi "echo" giữa lệnh gọi getentifcâu lệnh của bạn ? Điều đó sẽ gây ra $?để kiểm tra trạng thái thoát echo, không phải cuộc gọi của bạn getent.
chepner

4
Vâng tôi nghĩ bạn có nghĩa là 2>&1thay vì 2&>1.
Tim Ludwinski

Mã hoạt động trên đầu vào không trống, nhưng nếu $1không được đặt, câu lệnh if sẽ trả về true. Từ thử nghiệm của tôi, giải pháp sẽ là bọc $1trong dấu ngoặc kép : getent passwd "$1" > /dev/null 2&>1.
Vince

Vui lòng đánh dấu một câu trả lời
Efren

Câu trả lời:


292

bạn cũng có thể kiểm tra người dùng bằng idlệnh.

id -u namecung cấp cho bạn id của người dùng đó. nếu người dùng không tồn tại, bạn nhận được giá trị trả về lệnh ( $?)1


3
Đó là những gì tôi sử dụng. Xem superuser.com/questions/336275/find-out-if-user-name-exists
guettli

24
câu trả lời tuyệt vời - chỉ là một tinh chỉnh nhỏ hoạt động độc đáo ... user_exists = $ (id -u user> / dev / null 2> & 1; echo $?) user_exists = 0 nếu "user" tồn tại hoặc 1 nếu không
Pancho

5
@Pancho Tôi nghĩ rằng biến của bạn nên được đặt tên là user_doesnt_exist
Will Sheppard

1
@WillSheppard: Ở cấp độ chung, việc xử lý boolean trong bash theo ý kiến ​​của tôi chưa rõ ràng và tôi thường tránh các suy luận boolean ngầm trong mã của mình. Sau đây làm cho việc đọc thú vị và thú vị cả hai ủng hộ 0 = true và <not 0> = false cho mục đích bash, và trong khi không thực tế, căn chỉnh với tên biến tôi đã sử dụng từ phối cảnh boolean: stackoverflow.com/a/5431932 / 3051627 . stackoverflow.com/questions/2933843/ trên .
Pancho

2
Nhờ nhận xét của @ Pancho tôi có thể đạt được điều đó, chỉ bằng cách gửi lỗi đến chỗ trống và thực hiện validuser(){ [[ -n $(id -u "$1" 2>/dev/null) ]] && echo 1 || echo 0; }. Điều đó, khá nhiều trả về 1 nếu người dùng tồn tại hoặc 0 nếu không.
lu1s

31

Tại sao bạn không sử dụng

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

Nó sẽ trả về 1 (vì người dùng có tối đa 1 mục nhập) nếu người dùng tồn tại và 0 nếu không có.


19
Điều này không hoạt động nếu máy chủ đang sử dụng một hệ thống khác để quản lý việc sử dụng như NIS hoặc LDAP. Trong trường hợp này, bạn có thể sử dụnggetent passwd | grep -c '^username:'
Toby Jackson

1
cái này sẽ trả về 1 nếu bạn có tên người dùng, hãy nói "test1" và muốn tạo tên người dùng mới gọi là "test".
Marin Nedea

2
@MarinNedea dấu hai chấm :sau tên người dùng bảo vệ chống khớp chuỗi con bằng cách khớp với dấu tách trường, do đó hiệu ứng bạn mô tả sẽ không xảy ra.
Stéphane Gourmetichon

30

Không cần phải kiểm tra mã thoát một cách rõ ràng. Thử

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

Nếu điều đó không hiệu quả, có điều gì đó không ổn với bạn getenthoặc bạn có nhiều người dùng được xác định hơn bạn nghĩ.


23

Đây là những gì tôi đã làm trong một Freeswitchkịch bản khởi động 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

Tôi đề nghị sử dụng lệnh id vì nó kiểm tra sự tồn tại của tệp người dùng hợp lệ wrt passwd, điều này không cần thiết có nghĩa giống nhau:

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

Lưu ý: 0 là root uid.


12

Tôi đã sử dụng nó theo cách đó:

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

9

Cho đến nay, giải pháp đơn giản nhất:

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

>/dev/null 2>&1thể rút ngắn thành &>/dev/nullBash.


Vâng, cảm ơn!
Zane Hitchcox

7

Script để kiểm tra xem người dùng Linux có tồn tại hay không

Script Để kiểm tra xem người dùng có tồn tại hay không

#! /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
Tại sao nên sử dụng cat? grep $USER_NAME /etc/passwd >/dev/null 2>&1
Alexx Roche

Có Alexx Roche, không cần sử dụng mèo, tôi đã sử dụng để có cách tốt hơn để hình dung khái niệm cho người mới bắt đầu.
Bakul Gupta

6

Trả lời muộn nhưng fingercũng hiển thị thêm thông tin về người dùng

  sudo apt-get finger 
  finger "$username"

OP có thể không sử dụng Debian.
narendra-choudhary

3

Thật ra tôi không thể tái tạo vấn đề. Kịch bản như được viết trong câu hỏi hoạt động tốt, ngoại trừ trường hợp $ 1 trống.

Tuy nhiên, có một vấn đề trong kịch bản liên quan đến chuyển hướng stderr. Mặc dù hai hình thức &>>&tồn tại, trong trường hợp của bạn, bạn muốn sử dụng >&. Bạn đã chuyển hướng stdout, đó là lý do tại sao biểu mẫu &>không hoạt động. Bạn có thể dễ dàng xác minh nó theo cách này:

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

Bạn sẽ thấy một tập tin có tên 1trong thư mục hiện tại. Bạn muốn sử dụng 2>&1thay thế hoặc sử dụng này:

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

Điều này cũng chuyển hướng stdoutstderrđến /dev/null.

Cảnh báo Chuyển hướng stderrđến /dev/nullcó thể không phải là một ý tưởng tốt. Khi mọi thứ đi sai, bạn sẽ không có manh mối tại sao.


3

thông tin người dùng được lưu trữ trong / etc / passwd, vì vậy bạn có thể sử dụng "grep 'usename' / etc / passwd" để kiểm tra xem tên người dùng có tồn tại không. Trong khi đó, bạn có thể sử dụng lệnh shell "id", nó sẽ in id người dùng và id nhóm, nếu người dùng không tồn tại, nó sẽ in thông báo "không có người dùng như vậy".


2

Đăng nhập vào máy chủ. grep "tên người dùng" / etc / passwd Điều này sẽ hiển thị chi tiết người dùng nếu có.


3
Điều này cũng sẽ phù hợp với bất kỳ tên người dùng có chứa "tên người dùng". Ví dụ: "some_username". Bạn sẽ muốn làmif grep -q "^username:" /etc/passwd; then ...
maedox

2

Sử dụng 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

Tùy thuộc vào việc triển khai hệ vỏ của bạn (ví dụ Busybox so với người lớn), [nhà điều hành có thể bắt đầu một quy trình, thay đổi $?.

Thử

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

thay đổi $?cho tôi cùng một đầu ra. Đây là phiên bản bash:GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
slayedbylucifer

Hãy thửif test "$RES" == "0"; then ...
Eugen Rieck

1
$?sẽ được mở rộng trước khi [chạy, vì vậy đó không phải là vấn đề.
chepner

1
Thay vì kiểm tra kết quả của lệnh, bạn có thể kiểm tra lệnh trực tiếp: 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

Dưới đây là tập lệnh để kiểm tra phân phối HĐH và tạo Người dùng nếu không tồn tại và không làm gì nếu người dùng tồn tại.

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

Tạo người dùng hệ thống some_usernếu nó không tồn tại

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

0

Tôi thích giải pháp một dòng tốt đẹp này

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

và trong kịch bản:

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

sử dụng:

[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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.