Tüm kullanıcı adlarını ve / veya ev dizinlerini nasıl listeleyebilirim?


16

Makinedeki tüm kullanıcıların dizinlerini listelemek istiyorum.Genellikle, yapacağım:

ls -l /home

Ama bunu başka makinelerde konuşlandırılacak bir komut dosyasında kullanıyorum ve belki de o makinelerde ev olarak adlandırmıyorlar (örneğin myHome). Bu yüzden genelleştirmek istiyorum ls -l ~. Ama bu sadece kullanıcıların ev dirs adı yerine tüm kullanıcıların ev dirs adı listeler (temelde makinede kullanıcı adlarının bir listesini almak istiyorum). Nasıl genelleyebilirim?


19
Aslında, tüm kullanıcıların ev dizinlerinin herhangi bir dizinin alt dizinleri olduğuna dair bir garanti yoktur .
hobbs

17
@hobbs veya kullanıcı oturum açana kadar var olduklarını. Bu, gerçekten hızlı bir şekilde karmaşıklaşan görünüşte basit sorunlardan biridir.
EightBitTony

11
Akılda Keep ~genellikle eşdeğer /home/userdeğil, /homeya /home/*(daha yakın niyetinize görünmektedir olan).
Ethan Kaminski

2
@EightBitTony: ... ne de ana dizin var olduğunu herhangi garantisi yoktur hiç . Örneğin, Ubuntu kurulumumda, birkaç sistem kullanıcısı (dahil nobody) giriş dizinine sahipler /nonexistent, ki bu belli ki mevcut değil. (Tabii ki, bu kullanıcılar ayrıca parola karmalarını *ve kabuklarını /usr/sbin/nologinveya olarak ayarlamışlardır /bin/false, bu yüzden başlamak için normal anlamda giriş yapamazlar.)
Ilmari Karonen

1
Öte yandan, bir (eski okul) NFS sunucusu, işletim sistemi tarafından adıyla bilinmeyen kullanıcılar için ev dizinleri sunabilir.
rackandboneman

Yanıtlar:


45

Birçok sistem, bir var getentlisteye komutunu veya içeriğini sorgulamak Name Service gibi veritabanları passwd, group,services , protocols...

getent passwd | cut -d: -f6

Ana dizinleri listeler (6 inci edilebilir veritabanlarında kullanıcılar tüm kolon ayrılmış alanı) sayılan .

Kullanıcı adının kendisi ilk alandadır, bu nedenle kullanıcı adları listesi için:

getent passwd | cut -d: -f1

(bu kullanıcıların sisteme giriş yapabileceği veya ana dizininin oluşturulduğu anlamına gelmediğini, ancak sistem tarafından bilindiklerini, bir kullanıcı kimliğine çevrilebileceklerini unutmayın).

Numaralandırılamayan veritabanları için, olası her kullanıcı kimliğini ayrı ayrı deneyebilir ve sorgulayabilirsiniz:

getent passwd {0..65535} | cut -d: -f1,6

(burada uids'in 65535'te durduğunu varsayarsak (bazı sistemler daha fazlasını destekler) ve zsh'ın küme {x..y}ayracı genişlemesini destekleyen bir kabuk ). Ancak bunu LDAP, NIS +, SQL ... gibi kullanıcı veritabanının ağa bağlandığı (ve sınırlı yerel önbellekleme olduğu) sistemlerde yapmak istemezsiniz, çünkü bu çok fazla ağ trafiği anlamına gelebilir (ve dizin sunucusuna yüklenebilir) ) tüm bu sorguları yapmak için.

Bu, aynı kullanıcı kimliğini paylaşan birkaç kullanıcı varsa, her kullanıcı kimliği için yalnızca bir giriş alacağınız anlamına gelir.

Eğer yoksa getent, aşağıdakilere başvurabilirsiniz perl:

perl -le 'while (@e = getpwent) {print $e[7]}'

için getent passwd( $e[0]kullanıcı adları için) veya:

perl -le 'for ($i=0;$i<65536;++$i) {
  if (@e = getpwuid $i) {print $e[0] ": " $e[7]}}'

için getent passwd {0..65535}aynı uyarılar ile.

Kabuklarda, ancak sınırlı sayıda kullanıcı adı için (bu genişletme operatörü için desteklenen kullanıcı adlarında izin verilen karakterlerin listesi kabuktan kabuğa değişir) çalışan ~userana dizini almak için kullanabilirsiniz . birkaç mermi (dahil ) işe yaramaz ( kullanıcının adı oradaki bir değişkente saklandığında başvurmanız gerekir ). Yine de kullanıcı adlarının listesini almanın bir yolunu bulmanız gerekir.user~bash~$usereval

Bazı mermiler, bu kullanıcı adlarının listesini almak için yerleşik desteğe sahiptir.

  • bash: compgen -unumaralandırılabilen veritabanlarındaki kullanıcıların listesini döndürür.
  • zsh: $userdirsilişkilendirilebilir dizi kullanıcı adlarını ana dizinleriyle eşler (numaralandırılabilen veritabanlarıyla da sınırlıdır, ancak ~usernumaralandırılamayan bir veritabanında bulunan bir kullanıcı için genişletme yaparsanız , bir giriş eklenecektir $userdirs). Böylece şunları yapabilirsiniz:

    printf '%s => %s\n' "${(kv@)userdirs}"

    kullanıcıları ana dizinleriyle listelemek için.

    Bu sadece zshetkileşimli olduğunda çalışır .

  • tcsh, fishVe yash(tamamlarken mesela kullanıcı adlarını tamamlayabilirsiniz diğer üç kabukları olan ~<Tab>argümanlar), ancak programlı kullanıcı adları o listeyi elde edelim gibi görünmüyor.


OP'nin zorluğu getentorada olup olmayacağını bilmek olacak, ki bu bir dereceye kadar 'diğer makinelerinin' kapsamına bağlı.
EightBitTony

1
@EightBitTony, bir perlalternatif ekledim .
Stéphane Chazelas

1
Mac'te, muhtemelen Açık Dizin içeren bir şey.
SilverWolf - Monica'yı

@seaturtle, perl -le 'while (@e = getpwent) {print $e[7]}'macOS üzerinde iyi çalışıyor.
Stéphane Chazelas

1
@FloHe, bunlar kullanıcı adları. Unix sistemlerindeki çoğu kullanıcı, ömrü çalışan sistem hizmetlerine adanmış özel sistem kullanıcılarıdır. getent passwdkullanıcı veritabanını gösterir. İlk alan kullanıcı adı, 6. alan ise kullanıcıların giriş dizinidir.
Stéphane Chazelas

17

Kullanıcı ana dizinlerini listelemenin daha iyi bir yolu, ayrıştırmaktır /etc/passwd onları ve oradan ayıklamak ve nerede olabilecekleriyle ilgili herhangi bir varsayımda bulunmamaktır.

İkinci yorumunuza bakılırsa, aslında kullanıcı dizinlerini değil, kullanıcı dizinlerini istersiniz, bu durumda /etc/passwdyine de daha iyi bir seçimdir. Bazı Linux / UNIX makinelerinde yapılandırılmış diğer kullanıcı kimlik doğrulama mekanizmalarının (örn. LDAP) olacağını ve sonuç olarak sorgunuzun hayal edebileceğinizden daha karmaşık olduğunu, ancak /etc/passwdbaşlamak için iyi bir yer olduğunu unutmayın.


9
Ayrıca getentonu destekleyen sistemlere de bakın .
Kusalananda

6
Evet, getenther zaman ayrıştırmaktan daha iyidir /etc/passwd(“diğer kullanıcı kimlik doğrulama mekanizmaları” konusundaki endişeleri giderir).
Stephen Kitt

@Kusalananda Bir getentçözümle ilgili sorun , veri kaynağının sadece belirli bir değer için sorgulanmasının değil, numaralandırılabileceğini varsaymasıdır. Stéphane Chazelas bu sorunun cevabında ayrıntılı , ama ben bu sayfa üzerinde kaymağını olan herkes için bir yorum eklemek istiyorum ama.
Andrew Henle

7

Kısa cevap :

compgen -u

Orta cevap : Kullandığınız yana bash, sizin için tüm olası tamamlamaları listeleyebilirsiniz ~kullanarak compgen -A user. Bu çok yaygın bir kullanımdır, kısaltılabilir compgen -u. Bir kabuk yerleşimi olarak, compgenkendi kılavuz sayfası yoktur. Bunun yerine , dokümantasyon için bash (1) 'e bakın ve Programlanabilir Tamamlama bölümünü okuyun .

Daha kapsamlı bir alternatif

Taşınabilirlik konusunda aşırı endişeleriniz varsa, sahip olduğunuz diğer makinelere bile güvenemeyebilirsiniz bash. Bu durumda, bunu yapın:

(getent passwd ||
    dscl . -ls /Users dsAttrTypeNative:homeDirectory || 
    nidump passwd  ||
    cat /etc/passwd) 2>/dev/null  |  cut -d: -f6

Açıklama Uzun yanıt her şeyi dener, bu nedenle getentgeleneksel UNIX passwd düz dosyası olan MacOS'lar daha yeni /etc/nsswitch.conf (hem GNU / Linux hem de BSD birlikte gelir ) kullanıp kullanmadığına bakılmaksızın hemen hemen tüm UNIX sistemlerinde çalışır Dizin Hizmetleri¹ ( dscl), hatta eski, temalı MacOS X sürümleri ve NeXTSTEP ( nidump).

Sadelik Peki, ne kadar taşınabilir? Unix'in işleri yapmanın birçok yolu vardır ve bazen daha basit yeterlidir. Birini seçmeniz gerekiyorsa, getent passwd | cut -d: -f6kabuk komut dosyaları için tavsiye ederim .


Dipnot ¹: MacOS'u biraz kullanmadım, bu yüzden birisi benim için sözdizimini doğru aldığımı doğrulayabilirse (ve çıktıda karışıklık yaratacak herhangi bir sokak sütunu içermiyorsa cut), bu harika olurdu. Teşekkürler.

Dipnot ²: Önerdiğim ve yaptığım şeyler farklı olabilir. Şahsen, geleneksel cut -d: -f1 /etc/passwdolanı komut satırında daha sık kullanacağım . Onlarca kez tekrarlandıktan sonra, zihnim başka şeyler üzerinde çalışırken parmaklarım yazabilir.


2
Tüm Mac OS X makinelerinin, sistemle birlikte geldiği gibi bash olması garanti edilir. (
Zsh

Yeterince doğru, ama MacOS kullanırken, Apple uzun bir süre bash'ı güncellememişti ve her zaman değiştirmek zorunda olduğum huysuz bir sürüm 3 şeydi. Apple, bash güncelleme konusunda daha iyi oldu mu?
hackerb9


Doğru, bunu düşünmedim. Benim bash (macOS Sierra 10.12.6) versiyonum 3.2.57. (:
SilverWolf - Monica

Neyse, bashetti compgen -u2.04 2000 yılında yayımlanan bu yana
Stéphane Chazelas

2

Ne olmuş ls -l ~/..? Bu, ana dizininizin üst kısmındaki tüm dizinleri listeler.


4
Bu, yalnızca tüm ev dizinlerinin aynı dizine dayandığı sistemlerde çalışır, bu çok değildir ( /homeLinux sistemlerinde yaygın olduğunu düşünebilirsiniz , ancak bunu çalıştırdığınızda ne olur root?). Ev dizinlerini listelemek, karşılaşabileceğiniz tüm vakaları ele almak istiyorsanız tuzaklarla dolu bir maceradır, ayrıntılar için diğer cevaplara bakın.
Stephen Kitt

7
Muhtemelen OP'nin algılanan sorununa doğrudan cevap veren tek cevap budur . Ancak OP'nin altında yatan soruna cevap vermiyor .
boru

1
Bu cevaptaki değer neyi kaçırdığını ve neden daha yüksek oy alan diğer cevaplar kadar iyi olmadığını anlamaktır.
Criggie
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.