ฉันจะแสดงรายการผู้ใช้ที่เป็นมนุษย์ทั้งหมดที่ฉันสร้างได้อย่างไร ฉันลองcat /etc/passwd
แล้วและมันก็มีรายการมากมาย
ฉันจะแสดงรายการผู้ใช้ที่เป็นมนุษย์ทั้งหมดที่ฉันสร้างได้อย่างไร ฉันลองcat /etc/passwd
แล้วและมันก็มีรายการมากมาย
คำตอบ:
ผู้ใช้ที่เป็นมนุษย์มี UID เริ่มต้นที่ 1,000 ดังนั้นคุณสามารถใช้ข้อเท็จจริงนั้นเพื่อกรองผู้ที่ไม่ใช่มนุษย์:
cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1
วิธีนี้จะตัดฟิลด์ (ชื่อผู้ใช้) แรกและฟิลด์ที่คั่นด้วยโคลอน (UID) ที่สามจาก/etc/passwd
นั้นกรองสำหรับบรรทัดผลลัพธ์ที่ลงท้ายด้วยเครื่องหมายโคลอนและตัวเลขสี่หลักจากนั้นตัดฟิลด์ (ชื่อผู้ใช้) แรกจากนั้นทำให้คุณมีรายการ ผู้ใช้ที่มี UID ระหว่าง 1,000 ถึง 9999
หากคุณมีผู้ใช้มากกว่าเก้าพันคนในระบบของคุณสิ่งนี้จะล้มเหลว - แต่จำเป็นต้อง จำกัด ผลลัพธ์เป็นnobody
UID 4 หลักเพื่อไม่ให้จับ(UID 65534)
นี่เป็นคำตอบที่ยอมรับได้ในคำสั่งเดียวแทนที่จะเป็นสามคำตอบ :
awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd
และต้องขอบคุณ Karel ในความคิดเห็นnobody
ผู้ใช้จะถูกกรองออกด้วย
โดยส่วนตัวแล้วฉันชอบใช้แค่:
ls /home
เป็นที่ยอมรับว่านี่ไม่ใช่รายชื่อผู้ใช้ แต่เป็นรายการของโฮมไดเร็กตอรี่แทน ปัจจุบันผู้ใช้งานมนุษย์ที่มีอยู่ในระบบจะมีโฮมไดเร็กตอรี่/home
, แต่คุณอาจเห็นโฮมไดเร็กตอรี่ของผู้ใช้ในอดีตที่ถูกลบ, เช่นกัน
สิ่งนี้ใช้ได้กับวัตถุประสงค์ของฉันและอาจใช้ได้กับคุณเช่นกัน ตัวอย่างเช่นหากคุณต้องการลบบัญชีผู้ใช้ที่ปรากฎว่าไม่มีอยู่อีกต่อไป ( nonexistent-user
) และเรียกใช้คำสั่ง
sudo deluser nonexistent-user
มันจะบอกคุณว่าผู้ใช้รายนี้ไม่มีอยู่จริง
/home
เร็กตอรี่นอก(ที่ไม่ได้เชื่อมโยงกับ/home
) กว่าผู้ใช้ที่เป็นมนุษย์จะมี UID ต่ำกว่า 1,000 (หลังจากทั้งหมด) นี่เป็นวิธีที่ใช้กันโดยทั่วไปในการจัดการผู้จัดการหน้าจอ ผู้ใช้บนหน้าจอเข้าสู่ระบบซึ่งบางครั้งอาจทำเพื่อผู้ใช้ที่เป็นมนุษย์) ข้อเสียอย่างหนึ่งที่ค่อนข้างน้อยที่นี่คือที่lost+found
จะแสดงรายการในระบบที่มี/home
พาร์ทิชันแยกต่างหาก
useradd --no-create-home username
?
useradd --no-create-home
- โฮมไดเรกทอรีอาจมีอยู่แล้วหรืออาจถูกสร้างขึ้นหลังจากนั้นไม่นาน - แต่ls /home
วิธีการนี้ใช้ได้ผลดีสำหรับกรณีเหล่านั้น
ในขณะที่มันอาจจะดูเหมือนเป็นความคิดที่ชัดเจนจริงมีความคลุมเครือในความหมายของผู้ใช้ของมนุษย์ บัญชีผู้ใช้ถูกซ่อนอย่างจงใจจากหน้าจอเข้าสู่ระบบเพราะมันใช้เพื่อวัตถุประสงค์เฉพาะ (แต่โดยมนุษย์) เป็นผู้ใช้ที่เป็นมนุษย์หรือไม่? วิธีการเกี่ยวกับubuntu
ผู้ใช้ (UID 999) ในไลฟ์ซีดี? และบัญชีผู้เยี่ยมชมในอูบุนตูก็ถูกสร้างขึ้นทันทีและถูกทำลายหลังจากออกจากระบบ พวกเขาเป็นมนุษย์หรือไม่ สามารถสร้างตัวอย่างเพิ่มเติมได้
ดังนั้นจึงเหมาะสมที่มีคำตอบที่ไม่เทียบเท่าหลายคำตอบ วิธีแก้ปัญหาการทำงานของSaige Hamblinls /home
คือสิ่งที่ผู้คนจริงทำและถ้าคุณกำลังเขียนสคริปต์คุณอาจจะใช้เพียงว่า
ls /home
แข็งแกร่งมากขึ้นแต่บางทีคุณอาจมีผู้ใช้ที่ถูกลบออกไป แต่ยังมีโฮมไดเรกทอรีอยู่/home
และคุณต้องหลีกเลี่ยงการแสดงรายการ หรืออาจเป็นเพราะเหตุผลอื่นคุณต้องแน่ใจว่ามีเพียงรายการเท่านั้น/home
ที่สอดคล้องกับบัญชีจริงเท่านั้น
ในกรณีที่ผมขอแนะนำให้ผ่านชื่อของทุกอย่างใน/home
การgetent
(เพื่อดึงpasswd
รายการของผู้ใช้ที่มีชื่อเหล่านั้น) แล้วแยกและการแสดงผลเพียงฟิลด์ชื่อผู้ใช้ (มีgrep
, sed
หรือawk
ตามความต้องการของคุณ) หนึ่งในสิ่งเหล่านี้จะทำ:
getent passwd $(ls /home) | grep -o '^[^:]*'
getent passwd $(ls /home) | sed 's/:.*//'
getent passwd $(ls /home) | awk -F: '{print $1}'
สิ่งนี้ควรใช้งานได้ดีเนื่องจากคุณไม่ควรมีบัญชีผู้ใช้ที่มีช่องว่างหรืออักขระควบคุมในชื่อ ไม่สามารถโดยไม่ต้องกำหนดค่าอูบุนตูจะให้มัน ; และถ้าคุณทำคุณมีปัญหามากขึ้น ดังนั้นปัญหาปกติของการแยกวิเคราะห์ls
จึงไม่เหมาะสม แต่ถึงแม้ว่ามันจะไม่เป็นไรจริงๆถ้าคุณพิจารณาการแทนที่คำสั่งด้วยls
ความไม่พอใจอย่างสุนทรีย์หรือเป็นนิสัยที่ไม่ดีคุณอาจต้องการ:
getent passwd $(basename -a /home/*) | grep -o '^[^:]*'
getent passwd $(basename -a /home/*) | sed 's/:.*//'
getent passwd $(basename -a /home/*) | awk -F: '{print $1}'
สิ่งเหล่านี้ไม่รองรับช่องว่างหรืออักขระควบคุม ฉันให้พวกเขาเพียงเพราะ$(ls /home)
ดูผิดแม้ในขณะที่ถูกต้องและทำให้ผู้ใช้หลายคนถูวิธีที่ผิด ในสถานการณ์ส่วนใหญ่มีเหตุผลจริงที่ดีเพื่อหลีกเลี่ยงการแยกวิเคราะห์ls
และในสถานการณ์เหล่านั้นการแยกวิเคราะห์basename -a
มักจะไม่ดีเพียงเล็กน้อยเท่านั้น ในสถานการณ์นี้อย่างไรก็ตามเนื่องจากข้อ จำกัด เกี่ยวกับตัวละครที่อาจเกิดขึ้นจริงในชื่อผู้ใช้พวกเขาทั้งคู่ก็ดี
ฉันใช้getent
เป็นหลักเพราะยอมรับชื่อผู้ใช้เป็นอาร์กิวเมนต์เพื่อ จำกัด การส่งออก แต่ยังเพราะมันเป็นสากลมากกว่าการตรวจสอบ/etc/passwd
โดยตรงเล็กน้อยในกรณีที่สิ่งอำนวยความสะดวกการตรวจสอบและฐานข้อมูลรหัสผ่านให้บริการเครือข่าย
วิธีการนี้มีประโยชน์เพิ่มเติมกว่าls /home
ว่าในระบบที่มีการแยก/home
พาร์ทิชันมักจะปรากฏในการส่งออกของlost+found
ls /home
lost+found
จะปรากฏเฉพาะในกรณีที่มีผู้ใช้ (เรียกว่าlost+found
เป็นมนุษย์หรือไม่) ซึ่งไม่น่าจะเกิดขึ้นls /home
เป็น fine-- คุณlost+found
รู้ว่าคุณไม่ได้มีผู้ใช้ที่เรียกว่ามนุษย์ไม่บ่อยนักวิธีนี้ (ในรูปแบบใด ๆ ข้างต้น) จะสร้างผลลัพธ์ที่ไม่น่าพอใจ:
/home
, หรือไม่เลย, สิ่งนี้แนะนำ แต่ไม่ได้หมายความว่าบัญชีนั้นไม่ควรถูกนำมาพิจารณาเพื่อแสดงถึงผู้ใช้ที่เป็นมนุษย์ /home
วิธีการนี้จะแสดงเฉพาะผู้ใช้เมื่อมีการไดเรกทอรีที่มีชื่อเดียวกันใน/home
นั้นไม่ใช่ไดเรกทอรีบ้านของใครและพวกเขามีชื่อเดียวกันกับผู้ใช้ที่ไม่ใช่มนุษย์ - หรือประกอบด้วยคำที่คั่นด้วยช่องว่างหนึ่งหรือมากกว่านั้นมีชื่อเดียวกัน ในฐานะผู้ใช้ที่ไม่ใช่มนุษย์ - ผู้ใช้ที่ไม่ใช่มนุษย์บางรายอาจรวมอยู่ในผลลัพธ์ getent
การขอร้องแยกดังนั้นการแยกคำไม่ได้สร้างผลลัพธ์ที่น่าเกรงขาม แต่ความซับซ้อนนั้นไม่ได้รับการรับประกันโดยพื้นฐานถ้าคุณใช้/home
เป็นอย่างอื่นนอกเหนือจากที่สำหรับไดเรกทอรีบ้านของผู้ใช้ ไม่สร้างผลลัพธ์ที่เชื่อถือได้)ถ้าคุณตัดสินใจที่จะไปด้วยวิธีการที่รหัสผู้ใช้ตรวจสอบเพื่อให้แน่ใจว่าพวกเขาจะอยู่ในช่วงแนวโน้มสำหรับบัญชีที่เป็นตัวแทนของมนุษย์เช่นเดียวกับในคำตอบที่ได้รับการยอมรับหรือคำตอบของ Oliแล้วฉันขอแนะนำนี้สำหรับความกะทัดรัด:
getent passwd | grep -oP '^[^:]+(?=:x:\d{4}:)'
นี่ใช้นิพจน์ปกติ Perl ( -P
) เพื่อแสดง:
^
) ที่ไม่มี:
s ( [^:]+
) - นี่คือฟิลด์แรกเช่นเดียว:
กับตัวคั่นฟิลด์ในpasswd
(?=
)
) ฟิลด์รหัสผ่านx
- ควรเป็นx
เพราะในแฮ็กรหัสผ่าน Ubuntu ถูกเก็บไว้ในshadow
ฐานข้อมูลไม่ใช่passwd
ฐานข้อมูลที่อ่านได้ทั่วโลก:\d{4}:
)นี้จึงเป็นตัวแปรที่มีนัยสำคัญสั้นและค่อนข้างง่ายของเทคนิคในคำตอบที่ได้รับการยอมรับ (เทคนิคที่อธิบายไว้ก็ทำงานได้ดีเช่นกันและมีประโยชน์ในการพกพาไปยังระบบที่ไม่ใช่ GNU / Linux ซึ่งgrep
ไม่รองรับ-P
)
หากคุณต้องการที่จะรองรับ UIDs สูงมากและตรวจสอบnobody
อย่างชัดเจนคุณสามารถใช้วิธีในคำตอบของ Oli อย่างไรก็ตามคุณอาจต้องการพิจารณาหากผู้ใช้ที่มี UID สูงมากควรเป็นมนุษย์จริงๆหรือหากพวกเขามีแนวโน้มที่จะเป็นผู้ใช้ที่ไม่ใช่มนุษย์ (เช่นnobody
) ในทางปฏิบัติผู้ใช้ดังกล่าว - นอกเหนือจาก - เป็นnobody
เรื่องผิดปกติดังนั้นนี่เป็นการเรียกการตัดสินในส่วนของคุณ
การประนีประนอมที่เป็นไปได้คือการแสดงผู้ใช้ในช่วงของ UID ที่ได้รับการกำหนดให้กับผู้ใช้ที่สร้างขึ้นใหม่ไม่ใช่ผู้ใช้ "ระบบ" คุณสามารถตรวจสอบสิ่งนี้ได้ในadduser.conf
:
$ grep -E '^(FIRST|LAST)_UID' /etc/adduser.conf
FIRST_UID=1000
LAST_UID=29999
ต่อไปนี้เป็นสองวิธีในการแสดงรายการผู้ใช้ที่มี UID อยู่ในช่วง 1,000 ถึง 29999:
getent passwd | grep -oP '^[^:]+(?=:x:[12]?\d{4}:)'
getent passwd | awk -F: '999<$3 && $3<30000 {print $1}'
basename
เป็นที่น่าเกลียด ls
มันไม่ดีกว่า เหตุผลหลักที่เราไม่แยกวิเคราะห์ ls ก็คือมันเป็นงานที่สามารถทำได้โดยเครื่องมืออื่น ๆ ได้อย่างปลอดภัยและสะอาดไม่มีสไตล์ cd /home; getent passwd *
ในกรณีนี้เปลือก:
ls
มักเกี่ยวกับสไตล์ สัญลักษณ์แสดงหัวข้อย่อยที่ 2 เกี่ยวกับ "ผลลัพธ์ที่ไม่น่าพอใจ" ครอบคลุมถึงปัญหา แต่จะปรากฏในส่วนภายหลัง ฉันได้ป้อนข้อความใหม่เพื่อชี้แจงว่าทำไมการแยกวิเคราะห์ls
จึงเหมาะสมในสถานการณ์นี้ แม้ว่าcd /home; getent passwd *
จะใช้รูปแบบที่มักจะแสดงให้เห็นถึงวิธีการ SOUNDER ผมได้หลีกเลี่ยงมันเพื่อที่จะไม่นำไปสู่ผู้อ่านจะเชื่อว่าเนื้อหาของ/home
ไดเรกทอรีกับแปลกรายการเพิ่มไม่สอดคล้องกับผู้ใช้งานจริงอาจยังคงอย่างใดเป็นที่พึ่งเป็นแนวทางในสิ่งที่ มีผู้ใช้งานอยู่
TL; DR : เฉพาะผู้ใช้ที่เป็นมนุษย์เท่านั้นที่มี SystemAccount = false
อีกวิธีหนึ่งคือการแสดงรายการของในขณะที่ไม่สนใจรูls /var/lib/AccountsService/users/ | grep -v root
ต ตอนนี้มีการเล่นโวหาร - gdm, หน้าจอ greeter / login (หรือมากกว่า desktop manager อย่างเป็นทางการ) ก็แสดงเป็นผู้ใช้ด้วย ดังนั้นจากรายการเราไม่สามารถบอกได้ว่า gdm เป็นมนุษย์หรือไม่
SystemAccount=false
วิธีการที่มีประสิทธิภาพมากขึ้นและถูกต้องคือการไปผ่านไฟล์ในโฟลเดอร์ที่และหาที่ผู้ใช้มีการระบุไว้ว่ามี ร้องหนึ่งซับประสบความสำเร็จ
grep SystemAccount=false /var/lib/AccountsService/users/* | awk -F '/' '{gsub(":","/");print $6}'
mini.iso
และไม่มีผู้จัดการการแสดงผลหรือติดตั้ง X11) ฉันมีบัญชีผู้ใช้ที่มนุษย์คนหนึ่ง - ยัง/var/lib/AccountsService/users
เป็นไดเรกทอรีว่างเปล่า ฉันคาดหวังว่าสิ่งนี้จะไม่ทำงานในการติดตั้ง Ubuntu Server ที่ไม่ทันสมัย นอกจากนี้เมื่อนี้ไม่ทำงานก็ไม่ได้อยู่ภายใต้ความคิดที่ค่อนข้างเข้มงวดของสิ่งที่ทำให้บัญชีผู้ใช้ "คน": การทำให้ผู้ใช้ที่มีuseradd
แม้โดยไม่ต้อง ไม่สร้างแฟ้มใน--system
AccountsService/users
ฉันเข้าร่วมงานปาร์ตี้ฉันดูแลระบบเครือข่ายโดยใช้ LDAP มีโฮมไดเรกทอรีภายนอก/home
และ UID (เนื่องจากข้อผิดพลาดของสคริปต์) เป็นล้าน ๆ ดังนั้นจึงไม่มีคำตอบปัจจุบัน การทดสอบที่ใช้งานได้สำหรับฉันกำลังตรวจสอบว่าผู้ใช้มีเชลล์ล็อกอินที่ถูกต้องหรือไม่ เปลือกหอยที่ถูกต้องเป็นหนึ่งซึ่งเป็น บริษัท /etc/shells
จดทะเบียนใน แบบฟอร์มที่ง่ายที่สุด:
getent passwd | grep -wFf /etc/shells
ไฟล์อาจมีความคิดเห็น (หรือบรรทัดว่าง) ดังนั้นอาจมีการกรองพวกเขาออก:
getent passwd | grep -wFf <(grep '^/' /etc/shells)
root
(ซึ่งอาจไม่ควรพิจารณาว่าเป็นผู้ใช้ที่เป็นมนุษย์เนื่องจากมนุษย์มักจะกลายเป็นรูตชั่วคราวและเพื่อวัตถุประสงค์เฉพาะแทนที่จะใช้เพื่อการทำงานปกติ) ดูเหมือนว่ามีโอกาสน้อยที่จะล้มเหลวใน วิธีการที่สำคัญใด ๆ วิธีการในคำตอบอื่น ๆ (รวมถึงของฉัน) อาจล้มเหลวขึ้นอยู่กับวิธีการหากไดเรกทอรีบ้านไม่ได้อยู่ใน/home
ขยะอื่น ๆ ที่อยู่ใน/home
UIDs จะแปลกหรือระบบไม่ได้ใช้ DM คำตอบนี้ใช้ได้ดีในทุกสถานการณ์
บนระบบ buntu ผู้ใช้ปกติ (ผู้ใช้ที่เป็นมนุษย์) มี UID ที่ขึ้นต้นด้วย 1,000 ซึ่งกำหนดตามลำดับเมื่อสร้างบัญชีครั้งแรก สิ่งทั้งหมดนี้ทำให้เกิดขึ้นได้ก็คือบัญชีแรกที่สร้างขึ้นในระบบ buntu มี UID 1,000 รายการถัดไปที่สร้างขึ้นมี UID 1001 และอื่น ๆ
ดังนั้นวิธีที่ง่ายที่สุดในการแสดงรายการบัญชีผู้ใช้ที่เป็นมนุษย์ทั้งหมดในระบบในความคิดของฉันคือการตรวจสอบว่าคอลัมน์ที่สามใน/etc/passwd
ไฟล์ที่มี UID ของผู้ใช้มากกว่าหรือเท่ากับ 1,000 และน้อยกว่าสมมติว่า 2000 (เป็นไปได้ยากที่พีซีเดสก์ท็อปทั่วไปจะมีบัญชีผู้ใช้มากกว่าหนึ่งพันบัญชีคุณไม่คิดอย่างนั้นหรือ):
$ awk -F$':' '{ if ($3 >= 1000 && $3 < 2000) print $1; }' /etc/passwd
nobody
นอกจากนี้คุณยังจะต้องกรอง =)