ตรวจสอบว่ามีผู้ใช้อยู่หรือไม่


165

ฉันต้องการสร้างสคริปต์เพื่อตรวจสอบว่ามีผู้ใช้อยู่หรือไม่ ฉันใช้ตรรกะด้านล่าง:

# 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

ตอนนี้สคริปต์ของฉันทำงานได้ดี


ฉันคิดว่าเมื่อคุณใช้$?คุณจะได้รับรหัสส่งคืนของtestคำสั่ง ดูคำตอบด้านล่าง
user000001

นั่นคือรหัสที่แน่นอนที่คุณใช้อยู่ใช่ไหม ไม่มีคำสั่งดีบัก "echo" ระหว่างการเรียกไปยังgetentและใบifแจ้งยอดของคุณหรือไม่ ที่จะทำให้เกิด$?การตรวจสอบสถานะออกจากไม่ได้เรียกร้องให้echo getent
chepner

4
ใช่ฉันคิดว่าคุณหมายถึงแทน2>&1 2&>1
Tim Ludwinski

รหัสทำงานบนอินพุตที่ไม่ว่างเปล่า แต่ถ้า$1ไม่ได้ตั้งค่าคำสั่ง if จะส่งคืนจริง จากการทดสอบของฉัน, การแก้ปัญหาจะห่อในราคาคู่:$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> / dev / null 2> & 1; echo $?) user_exists = 0 ถ้า "ผู้ใช้" มีอยู่หรือ 1 ถ้าไม่ใช่
Pancho

5
@Pancho ฉันคิดว่าตัวแปรของคุณควรมีชื่อว่า user_doesnt_exist
Will Sheppard

1
@ WillSheppard: ในระดับทั่วไปการจัดการแบบบูลใน bash อยู่ในความคิดของฉันน้อยกว่าชัดเจนและฉันมักจะหลีกเลี่ยงการอนุมานแบบบูลีนโดยนัยในรหัสของฉัน ต่อไปนี้ทำให้การอ่านที่น่าสนใจและน่าสนใจทั้งสองชอบ 0 = จริงและ <ไม่ 0> = เท็จสำหรับวัตถุประสงค์ในการทุบตีและในขณะที่ไม่ใช่พฤตินัยให้ปรับตำแหน่งให้สอดคล้องกับชื่อตัวแปรที่ฉันใช้จากมุมมองบูลีนด้วย: stackoverflow.com/a/5431932 / stackoverflow.com/questions/2933843/… .
Pancho

2
ขอขอบคุณที่แสดงความคิดเห็น @ validuser(){ [[ -n $(id -u "$1" 2>/dev/null) ]] && echo 1 || echo 0; }พันโชของฉันสามารถบรรลุว่าเพียงโดยการส่งข้อผิดพลาดที่จะเป็นโมฆะและการทำ นั่นจะส่งกลับค่า 1 หากผู้ใช้มีอยู่หรือ 0 ถ้าไม่มี
lu1s

32

ทำไมคุณไม่ใช้

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

มันจะส่งคืน 1 (เนื่องจากผู้ใช้มีรายการสูงสุด 1 รายการ) หากผู้ใช้มีอยู่และ 0 หากไม่มี


19
สิ่งนี้ไม่ทำงานหากเซิร์ฟเวอร์ใช้ระบบอื่นเพื่อจัดการการใช้งานเช่น NIS หรือ LDAP ในกรณีนี้คุณสามารถใช้getent passwd | grep -c '^username:'
Toby Jackson

1
สิ่งนี้จะส่งคืน 1 หากคุณมีชื่อผู้ใช้สมมุติว่า "test1" และต้องการสร้างชื่อผู้ใช้ใหม่ที่ชื่อว่า "test"
Marin Nedea

2
@MarinNedea โคลอน:หลังจากชื่อผู้ใช้ป้องกันการจับคู่สตริงย่อยโดยจับคู่กับตัวคั่นฟิลด์ดังนั้นเอฟเฟกต์ที่คุณอธิบายจะไม่เกิดขึ้น
Stéphane Gourichon

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หรือคุณมีผู้ใช้งานมากกว่าที่คุณคิด


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 เพราะเป็นการทดสอบการมีอยู่ของผู้ใช้ที่ถูกต้องรายการไฟล์ wrt passwd ซึ่งไม่จำเป็นต้องหมายความว่าเหมือนกัน:

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

หมายเหตุ: 0 คือรูท uid



9

โดยวิธีที่ง่ายที่สุด:

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

>/dev/null 2>&1สามารถลงไป&>/dev/nullในทุบตี


ใช่ขอบคุณ!
Zane Hitchcox

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
Alexx Roche

ใช่ Alexx Roche ไม่จำเป็นต้องใช้แมวฉันได้ใช้เพื่อให้มีวิธีที่ดีกว่าในการมองเห็นแนวคิดสำหรับผู้เริ่มต้น
Bakul Gupta


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" มันจะพิมพ์ ID ผู้ใช้และกลุ่ม id หากผู้ใช้ไม่มีอยู่ก็จะพิมพ์ข้อความ "ไม่มีผู้ใช้ดังกล่าว"


2

เข้าสู่ระบบเซิร์ฟเวอร์ grep "ชื่อผู้ใช้" / etc / passwd นี่จะแสดงรายละเอียดผู้ใช้ถ้ามี


3
นี่จะตรงกับชื่อผู้ใช้ใด ๆ ที่มี "ชื่อผู้ใช้" เช่น "some_username" คุณต้องการจะทำif grep -q "^username:" /etc/passwd; then ...
maedox


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

การเปลี่ยนแปลง$?ให้ผลลัพธ์เดียวกัน นี่เป็นเวอร์ชั่นทุบตี: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

ด้านล่างเป็นสคริปต์เพื่อตรวจสอบการกระจาย OS และสร้างผู้ใช้หากไม่มีอยู่และไม่ทำอะไรเลยหากมีผู้ใช้อยู่

#!/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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.