Chcę wyświetlić listę wszystkich katalogów użytkowników na komputerze. Zazwyczaj zrobię:
ls -l /home
Ale używam go w skrypcie, który zostanie wdrożony na innych komputerach i być może na tych komputerach nie nazywają go domem (np. MyHome). Więc chcę to uogólnić ls -l ~
. Ale po prostu wyświetla listę katalogów domowych użytkowników zamiast nazwy katalogów domowych wszystkich użytkowników (w zasadzie chcę uzyskać listę nazw użytkowników na komputerze). Jak mogę to uogólnić?
bash
shell-script
eval
lakerda
źródło
źródło
~
ogólnie jest to odpowiednik/home/user
, brak/home
lub/home/*
(które wydają się być bliższe twojej intencji).nobody
) ma ustawiony katalog domowy na/nonexistent
, co oczywiście nie istnieje. (Oczywiście, ci użytkownicy mają również swoje hasło hash do zestawu*
i ich powłoki zestaw do/usr/sbin/nologin
lub/bin/false
, tak naprawdę nie może zalogować się w normalnym znaczeniu, aby rozpocząć.)Odpowiedzi:
Wiele systemów posiada
getent
komendy do listy lub kwerendy zawartości nazwa usługi baz danych, takich jakpasswd
,group
,services
,protocols
...Wyświetliłby katalogi domowe ( pole rozdzielone 6- tym dwukropkiem) wszystkich użytkowników w bazach danych, które można wyliczyć .
Sama nazwa użytkownika znajduje się w pierwszym polu, więc dla listy nazw użytkowników:
(zwróć uwagę, że nie oznacza to, że ci użytkownicy mogą zalogować się do systemu lub utworzono ich katalog domowy, ale że są oni znani w systemie, mogą zostać przetłumaczeni na identyfikator użytkownika).
W przypadku baz danych, których nie można wyliczyć, możesz spróbować wysłać zapytanie do każdego możliwego identyfikatora użytkownika osobno:
(tutaj przy założeniu, że UID zatrzyma się na 65535 (niektóre systemy obsługują więcej) i powłoka, która obsługuje
{x..y}
formę rozwijania nawiasów przez Zsh). Ale nie chcesz tego robić często w systemach, w których baza danych użytkowników jest podłączona do sieci (a lokalne buforowanie jest ograniczone), takich jak LDAP, NIS +, SQL ... ponieważ może to oznaczać duży ruch sieciowy (i obciążenie serwera katalogów ), aby wykonać wszystkie te zapytania.Oznacza to również, że jeśli kilku użytkowników korzysta z tego samego identyfikatora użytkownika, dostaniesz tylko jeden wpis dla każdego identyfikatora użytkownika, więc przegap inne.
Jeśli nie masz
getent
, możesz skorzystać zperl
:dla
getent passwd
($e[0]
dla nazw użytkowników) lub:za
getent passwd {0..65535}
tymi samymi zastrzeżeniami.W powłokach można użyć
~user
katalogu głównegouser
, ale w większości powłok, który działa tylko w przypadku ograniczonego zestawu nazw użytkowników (lista dozwolonych znaków w nazwach użytkowników obsługiwanych dla tego~
operatora rozszerzenia różni się w zależności od powłoki) kilka powłok (w tymbash
)~$user
nie będzie działać (należy skorzystać z opcji,eval
gdy nazwa użytkownika jest tam przechowywana w zmiennej). I nadal będziesz musiał znaleźć sposób na uzyskanie listy nazw użytkowników.Niektóre powłoki mają wbudowaną obsługę pobierania tej listy nazw użytkowników.
bash
:compgen -u
zwraca listę użytkowników w bazach danych, które można wyliczyć.zsh
:$userdirs
tablica asocjacyjna odwzorowuje nazwy użytkowników na ich katalog domowy (ogranicza się również do baz danych, które można wyliczyć, ale jeśli wykonasz~user
rozszerzenie dla użytkownika znajdującego się w bazie danych, której nie można wyliczyć, pozycja zostanie dodana$userdirs
). Możesz więc zrobić:aby wyświetlić listę użytkowników z ich katalogiem domowym.
Działa to tylko wtedy, gdy
zsh
jest interaktywne .tcsh
,fish
Ayash
trzy inne pociski, które mogą zakończyć nazwy użytkownika (na przykład przy wypełnianiu~<Tab>
argumentów), ale nie wygląda na to, że pozwalają uzyskać tę listę nazw użytkowników programowo.źródło
getent
tam będzie, co, jak sądzę, do pewnego stopnia zależy od zakresu ich „innych maszyn”.perl
alternatywę.perl -le 'while (@e = getpwent) {print $e[7]}'
działa dobrze na macOS.getent passwd
pokazuje bazę danych użytkowników. Pierwsze pole to nazwa użytkownika, szóste pole to katalog domowy użytkowników.Lepszym sposobem wylistowania katalogów domowych użytkowników jest ich parsowanie
/etc/passwd
i wyodrębnianie z nich, a nie przyjmowanie żadnych założeń dotyczących ich lokalizacji.Sądząc po drugim komentarzu, naprawdę chcesz nazwy użytkowników, a nie ich katalogi domowe, w którym to przypadku i tak
/etc/passwd
jest lepszym wyborem. Zauważ, że niektóre maszyny z systemem Linux / UNIX będą miały skonfigurowane inne mechanizmy uwierzytelniania użytkowników (np. LDAP), a zatem Twoje zapytanie jest bardziej złożone, niż można sobie wyobrazić, ale/etc/passwd
jest dobrym miejscem do rozpoczęcia.źródło
getent
systemy, które go obsługują.getent
zawsze jest lepsze niż parsowanie/etc/passwd
(rozwiązuje problem związany z „innymi mechanizmami uwierzytelniania użytkowników”).getent
rozwiązaniem polega na tym, że źródło danych można wyliczyć, a nie tylko zapytać o konkretną wartość. Jest to szczegółowo opisane w odpowiedzi Stéphane'a Chazelasa na to pytanie , ale pomyślałem, że dodam komentarz dla każdego, kto przejrzy tę stronę.Krótka odpowiedź :
Średnia odpowiedź : ponieważ używasz
bash
, możesz wymienić wszystkie możliwe uzupełnienia~
użyciacompgen -A user
. To takie powszechne użycie, można je skrócićcompgen -u
. Jako wbudowana powłoka,compgen
nie ma własnej strony podręcznika. Zamiast tego zobacz dokumentację bash (1) i przeczytaj sekcję Programowalne zakończenie .Bardziej dokładna alternatywa
Jeśli bardzo martwisz się przenośnością, możesz nawet nie być w stanie polegać na innych komputerach
bash
. W takim przypadku wykonaj następujące czynności:Wyjaśnienie Długa odpowiedź próbuje wszystkiego, więc będzie działać na prawie każdym systemie UNIX, niezależnie od tego, czy używa nowszego /etc/nsswitch.conf (zarówno GNU / Linux, jak i BSD
getent
), tradycyjnego płaskiego pliku passwd UNIX, MacOS Usługi katalogowe¹ (dscl
), a nawet starsze wydania MacOS X o tematyce kota i NeXTSTEP (nidump
).Prostota Ale jak bardzo potrzebujesz przenośności? Unix ma wiele sposobów robienia rzeczy, a czasem prostsze wystarczy. Jeśli musisz wybrać jeden, polecam
getent passwd | cut -d: -f6
dla skryptów powłoki .²Przypis ¹: Nie używałem MacOS trochę, więc jeśli ktoś może dla mnie potwierdzić, że mam poprawną składnię (a wynik nie zawiera żadnych zbłąkanych dwukropków, które mogłyby zepsuć
cut
), byłoby świetnie. Dzięki.Przypis ²: To, co polecam i co robię, może się różnić. Osobiście częściej używam tradycyjnego
cut -d: -f1 /etc/passwd
z wiersza poleceń. Po dziesięcioleciach powtarzania moje palce mogą pisać, podczas gdy mój umysł pracuje nad innymi rzeczami.źródło
bash
compgen -u
Co
ls -l ~/..
? Wyświetla listę wszystkich katalogów nadrzędnych katalogu domowego.źródło
/home
jest powszechne w systemach Linux, ale co się stanie, gdy uruchomisz to jakoroot
?). Listowanie katalogów domowych to przygoda pełna pułapek, jeśli chcesz poradzić sobie ze wszystkimi przypadkami, które możesz napotkać, zobacz inne odpowiedzi, aby uzyskać szczegółowe informacje.