Oluşturduğum tüm insan kullanıcıları nasıl listeleyebilirim? Ben denedim cat /etc/passwd
ve sadece bir sürü şey listeler.
Oluşturduğum tüm insan kullanıcıları nasıl listeleyebilirim? Ben denedim cat /etc/passwd
ve sadece bir sürü şey listeler.
Yanıtlar:
İ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/passwd
keser, 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).
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 nobody
kullanıcı da filtrelendi.
Ş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.
/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ı /home
bölümlere sahip sistemlerde listelenecek olmasıdır .
useradd --no-create-home username
?
useradd --no-create-home
- home dizini zaten var olabilir veya kısa bir süre sonra oluşturulabilir - ancak ls /home
bu durumlar için yöntem iyi çalışır.
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? ubuntu
Canlı 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 /home
insanların gerçekte yaptıklarıdır ve bir senaryo yazmazsanız, muhtemelen bunu kullanmalısınız.
ls /home
Daha Sağlam YapmakAncak, kaldırılmış ancak ana dizinleri hala mevcut olan kullanıcılarınız olabilir /home
ve bunları listelemekten kaçınmalısınız. Ya da başka bir nedenden ötürü, yalnızca /home
gerçek hesaplara karşılık gelen girişlerin listelendiğinden emin olmalısınız .
Bu durumda, ben her şeyi isimlerini geçirerek önermek /home
için getent
(almak için passwd
(olanlar adlarla kullanıcıların girdilerini), sonra izolatı ve ekran sadece adı alanında grep
, sed
ya awk
tercihinize 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 ls
vardır uygulanamaz. Ancak burada gerçekten iyi olsa da, ls
estetik 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 -a
genellikle ç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.
Kullandığım getent
argü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/passwd
dava doğrulama imkanı ve şifre veritabanında doğrudan ağ hizmetleri tarafından sağlanmaktadır.
Bu yöntemin, ls /home
ayrı bir /home
bölüme sahip sistemlerde , lost+found
genellikle çıktısında göründüğünden daha fazla yararı vardır ls /home
.
lost+found
yalnızca olası bir kullanıcı (insan ya da değil) denirse ortaya çıkacaktır lost+found
.ls /home
fine-- 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:
/home
veya 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
./home
Aslı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. getent
çağrılarla uygulanabilir, bu nedenle sözcük bölme sahte çıktı üretmez. Ancak karmaşıklık garanti edilmez; temel olarak, /home
kullanıcıların ev dizinleri için bir yer dışında bir şey kullanırsanız , bu yöntem güvenilir çıktı üretmez.)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:
^
) içermeyen bir satırın ( ) başındaki metin - bu, alan ayırıcısı gibi ilk alandır:
[^:]+
:
passwd
(?=
)
) parola alanı içermez x
- x
Ubuntu'da parola karmaları shadow
dünya tarafından okunabilir passwd
veritabanında değil, veritabanında depolandığından her zaman olmalıdır:\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 grep
desteklemeyen GNU / Linux olmayan sistemlere taşınabilir olma avantajına sahip -P
.)
Çok yüksek UID'leri barındırmak ve nobody
açı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 - nobody
nadirdir, 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}'
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 *
.
ls
genellikle 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 ls
iş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
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}'
mini.iso
ekran yöneticileri veya X11 yüklü ve yüklü olmayan), bir insan kullanıcı hesabım var - ancak /var/lib/AccountsService/users
boş 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
.
Partiye /home
katı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)
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 /home
UIDs garip veya sistem bir DM kullanmaz. Bu cevap tüm bu senaryolarda gayet iyi çalışıyor.
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
nobody
. =)