Tüm insan kullanıcıları listele


19

Oluşturduğum tüm insan kullanıcıları nasıl listeleyebilirim? Ben denedim cat /etc/passwdve sadece bir sürü şey listeler.

Yanıtlar:


18

İnsan kullanıcılarının 1000'den başlayan UID'leri vardır, bu nedenle bu gerçeği insan olmayanları filtrelemek için kullanabilirsiniz:

cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1

Bu, ilk (kullanıcı adı) ve üçüncü (UID) iki nokta üstüste ayrılmış alanları /etc/passwdkeser, ardından iki nokta üst üste ve dört basamakla biten sonuç satırlarını filtreler, ardından ilk (kullanıcı adı) alanını keser ve sizi 1000 ile 9999 arasında UID'li kullanıcılar.

Sisteminizde dokuz binden fazla kullanıcınız varsa, bu başarısız olur - ancak yakalanmamak için sonucu 4 basamaklı UID'lerle sınırlamak gerekir nobody(UID 65534).


15

Bu , kabul edilen cevabın yaptığı şeyi yapar, üç yerine tek bir komutla:

awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd

Yorumlarda yer alan Karel sayesinde nobodykullanıcı da filtrelendi.


@karel Evet, belki. UID ile filtrelemek yerine, bu kullanıcı adını açıkça filtreliyorum. O kadar yüksek bir UID ile meşru bir kullanıcı olması için bir neden olabilir ... Kim bilir;)
Oli

9

Şahsen sadece kullanmayı seviyorum:

ls /home

Kuşkusuz bu bir kullanıcı listesi değil, ev dizinlerinin bir listesidir. Şu anda sistemdeki mevcut kullanıcı kullanıcıları ev dizinlerine sahip olacak /home, ancak kaldırılan geçmiş kullanıcıların ev dizinlerini de görebilirsiniz.

Bu benim amacım için geçerlidir ve sizin için de işe yarayabilir. Örneğin, artık var olmayan bir kullanıcı hesabını silmek istiyorsanız ( nonexistent-user) ve komutu çalıştırın

sudo deluser nonexistent-user

sadece bu kullanıcının mevcut olmadığını söyleyecektir.


+1 Bu şekilde basit, çoğu deneyimli kullanıcının gerçekte yapacağı şeydir ve bence bir dizi UID'yi kontrol eden yöntemlerden daha az sağlam değildir. Bir insan kullanıcının dışında bir ana dizine sahip olması /home(buna bağlanmamıştır /home), bir kullanıcı kullanıcısının 1000'in altında bir UID'ye sahip olmasından daha az olasıdır (sonuçta, bu, bir görüntüleme yöneticisinin listelemesini engellemenin en yaygın yöntemidir giriş ekranında, bazen bir kullanıcı için yapılabilen bir kullanıcı). Buradaki nispeten küçük dezavantaj lost+found, ayrı /homebölümlere sahip sistemlerde listelenecek olmasıdır .
Eliah Kagan

Ancak küçük bir sorun: kullanıcı ile oluşturulmuşsa ne olur useradd --no-create-home username?
Sergiy Kolodyazhnyy

@Serginin sorun tanımındaki doğal belirsizlikten kaynaklandığını düşünüyorum. Giriş dizini olmayan bir hesap gerçekten bir insanı temsil ediyor mu? Uygulamada, bu tür hesaplar genellikle - kuşkusuz her zaman olmasa da - son derece uzmanlaşmış görevler (genellikle kendi ayrı hesapları olan kişiler tarafından) veya sisteme yalnızca belirli, sınırlı hizmetler yoluyla erişmeyi amaçlayan kullanıcılar için kullanılır. Tabii ki useradd --no-create-home- home dizini zaten var olabilir veya kısa bir süre sonra oluşturulabilir - ancak ls /homebu durumlar için yöntem iyi çalışır.
Eliah Kagan

4

Net bir fikir gibi görünse de, aslında insan kullanıcının anlamında bir belirsizlik vardır . Bir kullanıcı hesabı, yalnızca özel amaçlar için (ancak insanlar tarafından) bir insan kullanıcı için kullanıldığı için giriş ekranından kasıtlı olarak gizlenmiş mi? ubuntuCanlı CD'deki kullanıcı (UID 999) ne dersiniz ? Ve Ubuntu'daki konuk hesapları, oturumdan sonra anında oluşturulur ve yok edilir; onlar insan kullanıcılar mı? Daha fazla örnek tasarlanabilir.

Bu nedenle, eşdeğer olmayan çok sayıda yanıtın verilmesi uygundur. Saige Hamblin'in koşma çözümü , ls /homeinsanların gerçekte yaptıklarıdır ve bir senaryo yazmazsanız, muhtemelen bunu kullanmalısınız.

ls /homeDaha Sağlam Yapmak

Ancak, kaldırılmış ancak ana dizinleri hala mevcut olan kullanıcılarınız olabilir /homeve bunları listelemekten kaçınmalısınız. Ya da başka bir nedenden ötürü, yalnızca /homegerçek hesaplara karşılık gelen girişlerin listelendiğinden emin olmalısınız .

Bu durumda, ben her şeyi isimlerini geçirerek önermek /homeiçin getent(almak için passwd(olanlar adlarla kullanıcıların girdilerini), sonra izolatı ve ekran sadece adı alanında grep, sedya awktercihinize göre). Bunlardan herhangi biri şunları yapacaktır:

getent passwd $(ls /home) | grep -o '^[^:]*'
getent passwd $(ls /home) | sed 's/:.*//'
getent passwd $(ls /home) | awk -F: '{print $1}'

Adlarında boşluk veya kontrol karakterleri olan kullanıcı hesaplarına sahip olmamanız gerektiği için bu iyi çalışmalıdır; Ubuntu'yu izin verecek şekilde yeniden yapılandırmadan ; ve eğer yaparsanız, daha büyük sorunlarınız var. Böylece ayrıştırma ile olağan sorunlar lsvardır uygulanamaz. Ancak burada gerçekten iyi olsa da, lsestetik açıdan hoşnutsuz veya sadece kötü bir alışkanlıkla komut ikamelerini düşünürseniz , şunları tercih edebilirsiniz:

getent passwd $(basename -a /home/*) | grep -o '^[^:]*'
getent passwd $(basename -a /home/*) | sed 's/:.*//'
getent passwd $(basename -a /home/*) | awk -F: '{print $1}'

Bunlar boşluk veya kontrol karakterlerini de içermez. Onları sadece $(ls /home)doğru olduğunda bile yanlış göründüğü için sağlıyorum ve böylece birçok kullanıcıyı yanlış şekilde ovuyor. Çoğu durumda, ayrıştırmayı önlemek için gerçek ve iyi nedenler vardırls ve bu durumlarda ayrıştırma basename -agenellikle çok az daha az kötüdür. Ancak bu durumda, kullanıcı adlarında pratik olarak hangi karakterlerin oluşabileceğine ilişkin sınırlama nedeniyle , ikisi de iyidir.

Açıklama, Yararları ve Sakıncaları

Kullandığım getentargümanlar çıkışını kısıtlamak için gibi adlarını kabul ettiğinden ağırlıklı, ancak inceleyerek biraz daha evrenseldir nedeniyle de /etc/passwddava doğrulama imkanı ve şifre veritabanında doğrudan ağ hizmetleri tarafından sağlanmaktadır.

Bu yöntemin, ls /homeayrı bir /homebölüme sahip sistemlerde , lost+foundgenellikle çıktısında göründüğünden daha fazla yararı vardır ls /home.

  • Yukarıda sunulan daha sağlam yöntemle, lost+foundyalnızca olası bir kullanıcı (insan ya da değil) denirse ortaya çıkacaktır lost+found.
  • Etkileşimli komutları girerek ziyade bir senaryo yazıyoruz Ama eğer ls /homefine-- olduğunu sen adlı bir insan kullanıcı yok biliyorum lost+found.

Nadiren, bu yöntem (yukarıdaki varyasyonların herhangi birinde) tatmin edici olmayan çıktılar üretecektir:

  • Bir kullanıcının ana dizini dışarıda mevcutsa /homeveya hiç değilse, bu, hesabın bir insan kullanıcıyı temsil ettiği düşünülmemesi gerektiğini ima eder. Bu yöntem, yalnızca aynı adda bir dizin olduğunda kullanıcıları listeler /home.
  • /homeAslında hiç kimsenin ana dizini olmayan ek dizinler oluşturduysanız ve mevcut olmayan bir kullanıcıyla aynı ada sahip olurlarsa veya bir veya daha fazla aynı ada sahip boşluklarla ayrılmış kelimelerden oluşurlarsa mevcut bir insan olmayan kullanıcı olarak - o zaman bazı insan olmayan kullanıcılar çıktıya dahil edilebilir.
    (Bu yöntem bir döngü ve ayrı getentçağrılarla uygulanabilir, bu nedenle sözcük bölme sahte çıktı üretmez. Ancak karmaşıklık garanti edilmez; temel olarak, /homekullanıcıların ev dizinleri için bir yer dışında bir şey kullanırsanız , bu yöntem güvenilir çıktı üretmez.)

UID Kontrolünü Basitleştirme

Kabul edilen cevapta veya Oli'nin yanıtında olduğu gibi, kullanıcıları temsil eden hesaplar için olası aralıkta olduklarından emin olmak için kullanıcı kimliklerini kontrol eden bir yöntemle gitmeye karar verirseniz , bunu kısaca tavsiye ederim:

getent passwd | grep -oP '^[^:]+(?=:x:\d{4}:)'

Bu, aşağıdakileri göstermek için bir Perl normal ifadesi ( -P) kullanır:

  • s ( ^) içermeyen bir satırın ( ) başındaki metin - bu, alan ayırıcısı gibi ilk alandır:[^:]+:passwd
  • öncesinde (ancak (?= )) parola alanı içermez x- xUbuntu'da parola karmaları shadowdünya tarafından okunabilir passwdveritabanında değil, veritabanında depolandığından her zaman olmalıdır
  • ve tam olarak 4 basamaktan oluşan bir UID alanı ( :\d{4}:).

Bu nedenle, bu, kabul edilen cevaptaki tekniğin önemli ölçüde daha kısa ve biraz daha basit bir çeşididir . (Burada açıklanan teknik de iyi çalışıyor ve grepdesteklemeyen GNU / Linux olmayan sistemlere taşınabilir olma avantajına sahip -P.)

"İnsan" UID Serisini Yeniden Düşünmek

Çok yüksek UID'leri barındırmak ve nobodyaçıkça kontrol etmek istiyorsanız, Oli'nin cevabındaki yöntemi kullanabilirsiniz . Bununla birlikte, çok yüksek UID'leri olan kullanıcıların gerçekten insan olarak kabul edilmesi gerekip gerekmediğini veya başka bir özel amaçlı insan olmayan kullanıcı (örneğin nobody) olma olasılıklarının daha yüksek olup olmadığını düşünmek isteyebilirsiniz . Uygulamada, bu tür kullanıcılar - ayrıca - nobodynadirdir, bu yüzden bu sizin açınızdan bir karar çağrısıdır.

Olası bir uzlaşma, gerçekte yeni oluşturulan, "sistem" olmayan kullanıcılara atanan UID aralığındaki kullanıcıları listelemektir . Bunun için kontrol edebilirsiniz inadduser.conf :

$ grep -E '^(FIRST|LAST)_UID' /etc/adduser.conf
FIRST_UID=1000
LAST_UID=29999

UID'leri 1000 ile 29999 arasında değişen kullanıcıları listelemenin iki yolu şunlardır:

getent passwd | grep -oP '^[^:]+(?=:x:[12]?\d{4}:)'
getent passwd | awk -F: '999<$3 && $3<30000 {print $1}'

Stilistik olarak hoş olmak istiyorsan basename, çirkin. Bundan daha iyi değil ls. L'leri ayrıştırmamamızın temel nedeni, diğer araçlarla stil değil , çok daha güvenli ve temiz bir şekilde yapılabilecek bir iş olmasıdır . Bu durumda, kabuk: cd /home; getent passwd *.
muru

Size / evde güvenilmez olduğunuzu kabul ediyorum (benim için işe yaramaz, cevabımı görün). Sadece diyorum ki stil hakkında vaaz edecekseniz nitpick yapmayı bekleyin.
muru

muru Orijinal ifademin insanları ayrıştırmadan kaçınmanın lsgenellikle stil ile ilgili olduğunu düşünmelerini nasıl yanıltabileceğini görüyorum . "Yetersiz çıktı" ile ilgili 2. madde işareti sorunu ele aldı, ancak daha sonraki bir bölümde ortaya çıktı. Bu durumda ayrıştırma lsişleminin neden uygun olduğunu açıklığa kavuşturdum . Genellikle daha sağlam bir yaklaşımı gösteren bir form almasına rağmen , okuyucuların dizin içeriğinin, gerçek kullanıcılara karşılık gelmeyen garip ek girişlerle inanmalarına neden olmamasını sağlamak için kaçındım, yine de bir şekilde neye rehber olabileceğine güvenebilirsiniz. kullanıcılar var. cd /home; getent passwd */home
Eliah Kagan

1

TL; DR : Yalnızca insan kullanıcıların SystemAccount = false değeri var

Diğer bir yol, kök yoksayılırken çıktılarını listelemektir ls /var/lib/AccountsService/users/ | grep -v root. Şimdi, bir tuhaflık - gdm var, bir karşılama / giriş ekranı (veya daha resmi olarak masaüstü yöneticisi) de kullanıcı olarak listeleniyor. Yani sadece listeden gdm'nin insan olup olmadığını söyleyemeyiz.

Daha etkili ve doğru bir yaklaşım, o klasördeki dosyaları gözden geçirmek ve hangi kullanıcıların sahip olarak listelendiğini bulmaktır SystemAccount=false. Tek astarlı körük,

grep SystemAccount=false /var/lib/AccountsService/users/* | awk -F '/' '{gsub(":","/");print $6}'


1
Bazen kullanışlı olsa da, bu nispeten yaygın bazı senaryolarda başarısız olur. Örneğin, Ubuntu 15.04 minimum sistemimde ( mini.isoekran yöneticileri veya X11 yüklü ve yüklü olmayan), bir insan kullanıcı hesabım var - ancak /var/lib/AccountsService/usersboş bir dizin. Bunun benzer bir Ubuntu Sunucu kurulumunda da çalışmayacağını düşünüyorum. Dahası, bu işe yaradığında, bir kullanıcı hesabını "insan" yapan şeylerin kısıtlayıcı bir nosyonu altında bunu yapar: bir kullanıcıyı useradd, olmadan da yapmak--system bir dosya oluşturmaz AccountsService/users.
Eliah Kagan

1

Partiye /homekatıldığımda, milyonlarca ev dizini ve UID (komut dosyası hatası nedeniyle) olan LDAP kullanan bir ağ sistemini denetliyorum. Dolayısıyla, mevcut cevapların hiçbiri işe yaramıyor. Benim için çalışan test, kullanıcının geçerli bir giriş kabuğuna sahip olup olmadığını kontrol etmektir. Geçerli bir kabuk, içinde listelenen kabuktur /etc/shells. En basit form:

getent passwd | grep -wFf /etc/shells

Dosya yorumlar (veya boş satırlar) içerebilir, bu nedenle bunları filtrelemek gerekebilir:

getent passwd | grep -wFf <(grep '^/' /etc/shells)

+1 Bu, şimdiye kadar önerilen en sağlam yaklaşım olabilir. Gösterme dezavantajına sahip olmasına rağmen root( muhtemelen bir insan kullanıcı olarak görülmemelidir, çünkü insanlar normal işlerinde kullanmak yerine genellikle geçici olarak ve belirli amaçlar için kökleşir), başarısız olma olasılığı en az gibi görünüyor önemli bir yol. Ev dizinleri değilse (benim de dahil) diğer yanıtlar yöntemler, kullanılan yönteme göre, başarısız olabilir /home, diğer çöp olduğu içinde /homeUIDs garip veya sistem bir DM kullanmaz. Bu cevap tüm bu senaryolarda gayet iyi çalışıyor.
Eliah Kagan

1

Buntu sistemlerinde, normal kullanıcıların (insan kullanıcılar, yani 1000'den başlayan UID'leri vardır ve bunlar hesaplar ilk oluşturulduğunda kendilerine sırayla atanır. Tüm bunlar, bir buntu sisteminde oluşturulan ilk hesabın 1000 UID değerine sahip olmasıdır. Oluşturulan bir sonraki 1001 UID değerine sahiptir ve bu böyle devam eder.

Bu nedenle, sistemde bulunan tüm insan kullanıcı hesaplarını listelemenin en basit yolu, bence /etc/passwd, kullanıcının UID'sini içeren dosyadaki üçüncü sütunun 1000'den büyük veya ona eşit olup olmadığını kontrol etmektir , diyelim ki 2000 (tipik bir masaüstü bilgisayarın binden fazla kullanıcı hesabına sahip olması pek olası değildir, öyle değil mi?):

$ awk -F$':' '{ if ($3 >= 1000 && $3 < 2000) print $1; }' /etc/passwd

Oli'nin cevabını ayrıntılarıyla açıkladığınız için teşekkürler. Ayrıca filtrelemeniz gerekir nobody. =)
anatoly techtonik

1
Bunu yapmak zorunda değilsiniz, çünkü kimsenin 65534 UID'si yoktur ve bu nedenle diğer tüm insan olmayan kullanıcı hesapları gibi otomatik olarak filtrelenir.
misha
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.