Wyświetl listę wszystkich użytkowników

19

Jak mogę wyświetlić listę wszystkich utworzonych przeze mnie użytkowników? Próbowałem cat /etc/passwdi po prostu wymienia wiele rzeczy.

anatoly techtonik
źródło

Odpowiedzi:

18

Użytkownicy mają identyfikatory UID zaczynające się od 1000, więc możesz użyć tego faktu, aby odfiltrować osoby niebędące ludźmi:

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

To odcina pierwsze (nazwa użytkownika) i trzecie (UID) pola rozdzielane dwukropkiem /etc/passwd, następnie filtruje wynikowe linie, które kończą się dwukropkiem i czterema cyframi, a następnie wycina z tego pierwsze pole (nazwa użytkownika), pozostawiając ci listę użytkownicy z identyfikatorami UID między 1000 a 9999.

Jeśli masz w systemie ponad dziewięć tysięcy użytkowników, to się nie powiedzie - ale konieczne jest ograniczenie wyniku do 4-cyfrowych nobodyidentyfikatorów UID, aby nie zostać złapanym (UID 65534).


źródło
15

Robi to prawie tak samo, jak akceptowana odpowiedź , tylko w jednym poleceniu zamiast trzech:

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

Dzięki Karelowi w komentarzach nobodyużytkownik jest również odfiltrowywany.

Oli
źródło
@karel Tak, może. Zamiast filtrować według UID, wyraźnie odfiltrowuję tę nazwę użytkownika. Może istnieć powód, dla którego uprawniony użytkownik z tak wysokim identyfikatorem UID ... Kto wie;)
Oli
9

Osobiście lubię używać tylko:

ls /home

Trzeba przyznać, że nie jest to lista użytkowników, ale lista ich katalogów domowych. Obecnie istniejący użytkownicy systemu w systemie będą mieli katalogi domowe /home, ale możesz także zobaczyć katalogi domowe użytkowników, którzy zostali usunięci.

Działa to dla moich celów i może również działać dla twojego. Na przykład, jeśli chcesz usunąć konto użytkownika, które, jak się okazuje, już nie istnieje ( nonexistent-user) i uruchom polecenie

sudo deluser nonexistent-user

powie Ci tylko, że ten użytkownik nie istnieje.

Sam Hamblin
źródło
+1 Ten sposób jest prosty, tak naprawdę zrobiliby najbardziej doświadczeni użytkownicy, i myślę, że jest nie mniej niezawodny niż metody sprawdzające zakres UID. Wydaje się mniej prawdopodobne, że ludzki użytkownik będzie miał katalog domowy na zewnątrz /home(do którego nie jest dowiązanie symboliczne /home), niż że ludzki użytkownik będzie miał UID poniżej 1000 (w końcu jest to najczęstsza metoda powstrzymywania menedżera wyświetlania od wyświetlania użytkownik na ekranie logowania, co czasami może być zrobione dla użytkownika). Jedyną stosunkowo niewielką wadą jest to, że lost+foundzostaną wymienione w systemach z oddzielnymi /homepartycjami.
Eliah Kagan
Mały problem: co się stanie, jeśli użytkownik został utworzony useradd --no-create-home username?
Sergiy Kolodyazhnyy
@Serg Myślę, że sprowadza się to do niejednoznaczności wynikającej z opisu problemu. Czy konto bez katalogu domowego naprawdę reprezentuje użytkownika? W praktyce takie konta są zwykle - choć co prawda nie zawsze - wykorzystywane do wysoce wyspecjalizowanych zadań (zwykle przez osoby posiadające własne oddzielne konta) lub użytkowników zamierzających uzyskać dostęp do systemu tylko za pośrednictwem określonych, ograniczonych usług. Oczywiście istnieje inny przypadek użycia useradd --no-create-home- katalog domowy może już istnieć lub może zostać utworzony wkrótce potem - ale ls /homemetoda działa dobrze w tych przypadkach.
Eliah Kagan
4

Chociaż może się to wydawać jednoznacznym pomysłem, w rzeczywistości w znaczeniu ludzkiego użytkownika występuje dwuznaczność . Czy konto użytkownika celowo jest ukryte przed ekranem logowania, ponieważ jest używane wyłącznie do celów specjalistycznych (ale przez ludzi) jako użytkownik? Co z ubuntuużytkownikiem (UID 999) na Live CD? Konta gości w Ubuntu są tworzone w locie i niszczone po wylogowaniu; czy są to ludzie? Można wymyślić więcej przykładów.

Dlatego dobrze jest, jeśli podano wiele nie równoważnych odpowiedzi. Rozwiązanie Saige Hamblin w biegu ls /homejest to, co ludzie faktycznie zrobić i chyba piszesz skrypt, należy prawdopodobnie tylko użyć.

Zwiększanie ls /homeniezawodności

Ale może masz użytkowników, którzy zostali usunięci, ale których katalogi domowe nadal istnieją /homei musisz ich unikać. A może z jakiegoś innego powodu musisz się upewnić, /homeże wymienione są tylko wpisy na koncie rzeczywistym.

W tym przypadku proponuję przechodząc nazwiska wszystko w /homecelu getent(aby odzyskać passwddane użytkowników z tymi nazwami), następnie wyizolować i wyświetlać jedynie polu nazwy użytkownika (z grep, sedlub awk, zgodnie z preferencjami). Każdy z nich zrobi:

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

Powinno to działać dobrze, ponieważ nie powinieneś mieć kont użytkowników ze spacjami lub znakami kontrolnymi w ich nazwach; nie może tego zrobić bez ponownej konfiguracji Ubuntu, aby na to pozwolić ; a jeśli tak, masz większe problemy. W związku z tym zwykłe problemy z parsowaniemls nie mają zastosowania. Ale nawet jeśli jest to naprawdę w porządku, jeśli weźmiesz pod uwagę zastępowanie poleceń lsnieprzyjemnym estetycznie lub po prostu złym nawykiem, możesz preferować:

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

Nie uwzględniają też białych znaków ani znaków kontrolnych. Zapewniam je tylko dlatego, $(ls /home)że wygląda źle, nawet gdy jest to właściwe, a zatem pociera wielu użytkowników w niewłaściwy sposób. W większości sytuacji istnieją rzeczywiste, dobre powody, aby unikać analizowanials , a w takich sytuacjach przetwarzanie basename -ajest zwykle tylko nieznacznie mniej złe. Jednak w tej sytuacji, ze względu na ograniczenie tego, jakie znaki mogą praktycznie występować w nazwach użytkowników , oba są w porządku.

Wyjaśnienie, zalety i wady

Używam getentgłównie dlatego, że akceptuje nazwy użytkowników jako argumenty w celu ograniczenia wyników, ale także dlatego, że jest nieco bardziej uniwersalny niż /etc/passwdbezpośrednie sprawdzanie , w przypadku gdy usługi uwierzytelniania zapewniają bazę danych haseł i usługi.

Ta metoda ma tę dodatkową zaletę, ls /homeże w systemach z oddzielną /homepartycją lost+foundzwykle pojawia się na wyjściu ls /home.

  • Dzięki bardziej niezawodnej metodzie przedstawionej powyżej, lost+foundpojawi się tylko wtedy, gdy zdarzy się, że zadzwoni użytkownik (człowiek lub nie) lost+found, co jest mało prawdopodobne.
  • Ale jeśli jesteś wprowadzania komend interaktywnie zamiast pisania skryptu, ls /homejest fine-- ty wiesz, że nie ma człowieka użytkownika o nazwie lost+found.

Nierzadko ta metoda (w dowolnej z powyższych odmian) generuje niezadowalającą wydajność:

  • Jeśli katalog domowy użytkownika istnieje na zewnątrz /homelub wcale, sugeruje to, ale nie oznacza, że ​​konto nie powinno być traktowane jako reprezentujące użytkownika. Ta metoda wyświetla listę użytkowników tylko wtedy, gdy istnieje katalog o tej samej nazwie /home.
  • Jeśli utworzyłeś w nim dodatkowe katalogi, /homektóre w rzeczywistości nie są niczyim katalogiem domowym, a tak się składa , że mają taką samą nazwę jak istniejący użytkownik inny niż człowiek - lub składają się ze słów oddzielonych białymi spacjami, z których co najmniej jeden ma taką samą nazwę jako istniejący użytkownik inny niż człowiek, wówczas niektórzy użytkownicy niebędący ludźmi mogą zostać włączeni do wyniku.
    (Metodę tę można zaimplementować za pomocą pętli i osobnych getentwywołań, dzięki czemu dzielenie słów nie daje fałszywych wyników. Ale złożoność nie jest uzasadniona; zasadniczo, jeśli używasz /homeczegoś innego niż miejsce na katalogi domowe użytkowników, ta metoda będzie nie produkują wiarygodnych wyników).

Uproszczenie sprawdzania UID

Jeśli zdecydujesz się na metodę, która sprawdza identyfikatory użytkowników, aby upewnić się, że znajdują się one w prawdopodobnym zakresie dla kont reprezentujących ludzi, tak jak w zaakceptowanej odpowiedzi lub odpowiedzi Oli , sugeruję to dla zwięzłości:

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

Używa wyrażenia regularnego Perl ( -P), aby pokazać:

  • tekst na początku wiersza ( ^) nie zawierającego :s ( [^:]+) - jest to pierwsze pole, podobnie jak :separator pól wpasswd
  • który poprzedza, ale nie zawiera ( (?= )) pola hasła x- zawsze powinno być x, ponieważ w Ubuntu skróty haseł są przechowywane w shadowbazie danych, a nie w passwdbazie danych odczytywalnej na całym świecie
  • oraz pole UID składające się z dokładnie 4 cyfr ( :\d{4}:).

Jest to zatem znacznie krótszy i nieco prostszy wariant techniki w przyjętej odpowiedzi . (Opisana tam technika również działa dobrze i ma tę zaletę, że jest przenośna dla systemów innych niż GNU / Linux, których grepnie obsługuje -P.)

Ponowne rozpatrzenie zakresu UID „Ludzkiego”

Jeśli chcesz uwzględnić bardzo wysokie identyfikatory UID i nobodywyraźnie je sprawdzić , możesz użyć metody z odpowiedzi Oli . Możesz jednak rozważyć, czy użytkownicy o bardzo wysokich identyfikatorach UID naprawdę powinni zostać uznani za ludzi, czy też bardziej prawdopodobne jest, że będą to użytkownicy o innym przeznaczeniu niż ludzie (jak nobody). W praktyce tacy użytkownicy - poza tym - nobodysą rzadcy, więc tak naprawdę jest to decyzja z twojej strony.

Możliwym kompromisem jest wyświetlenie listy użytkowników w zakresie identyfikatorów UID , którzy faktycznie są przypisywani do nowo utworzonych użytkowników niesystemowych. Możesz to sprawdzić wadduser.conf :

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

Oto dwa sposoby wyświetlania listy użytkowników, których UID mają zakres od 1000 do 29999:

getent passwd | grep -oP '^[^:]+(?=:x:[12]?\d{4}:)'
getent passwd | awk -F: '999<$3 && $3<30000 {print $1}'
Eliah Kagan
źródło
Jeśli chcesz być przyjemny stylistycznie, basenamejest brzydka. To nie jest lepsze niż ls. Głównym powodem, dla którego nie analizujemy, jest to, że jest to praca, którą inne narzędzia mogą wykonać znacznie bezpieczniej i czysto, a nie stylowo. W tym przypadku, powłoka: cd /home; getent passwd *.
muru
Zgadzam się z tym, że dom jest zawodny (dla mnie to bezużyteczne, patrz moja odpowiedź). Mówię tylko, że jeśli zamierzasz głosić o stylu, spodziewaj się nitpicking.
muru
@muru Widzę, jak moje oryginalne sformułowania mogą wprowadzać ludzi w błąd, że unikanie parsowania lsdotyczy zazwyczaj stylu. Drugi punkt dotyczący „niezadowalającej wydajności” dotyczył tego problemu, ale pojawia się w dalszej części. Przeredagowałem, aby wyjaśnić, dlaczego analiza lsjest odpowiednia w tej sytuacji . Chociaż cd /home; getent passwd *przybiera formę często wskazującą na podejście sygnalizatora, unikałem go, aby nie doprowadzić czytelników do przekonania, że ​​zawartość /homekatalogów, z dziwnymi dodanymi wpisami nie odpowiadającymi prawdziwym użytkownikom, nadal może być w jakiś sposób wykorzystywana jako przewodnik po tym, co użytkownicy istnieją.
Eliah Kagan
1

TL; DR : tylko użytkownicy mają SystemAccount = false

Innym sposobem jest wyświetlenie listy wyników, ignorując root ls /var/lib/AccountsService/users/ | grep -v root. Teraz jest dziwactwo - gdm, ekran powitania / logowania (lub bardziej formalnie menedżer pulpitu) jest również wymieniony jako użytkownik. Więc po prostu z listy nie możemy stwierdzić, czy gdm jest człowiekiem, czy nie.

Bardziej wydajnym i poprawnym podejściem jest przejrzenie plików w tym folderze i sprawdzenie, którzy użytkownicy są na liście jako posiadający SystemAccount=false. Osłona jednowarstwowa osiąga to

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

Sergiy Kolodyazhnyy
źródło
1
Chociaż czasami jest to przydatne, nie udaje się to w niektórych stosunkowo powszechnych scenariuszach. Na przykład w moim minimalnym systemie Ubuntu 15.04 (instalowanym zi mini.isobez menedżerów wyświetlania lub X11) mam jedno konto użytkownika - /var/lib/AccountsService/usersjest to jednak pusty katalog. Oczekuję, że to również nie zadziała w przypadku instalacji gotowego serwera Ubuntu. Ponadto, gdy to działa, robi to pod nieco ograniczonym pojęciem, co powoduje, że konto użytkownika jest „ludzkie”: utworzenie użytkownika useradd, nawet bez niego --system , nie tworzy pliku AccountsService/users.
Eliah Kagan
1

Dołączając do partii, nadzoruję systemy sieciowe korzystające z LDAP, mające /homemiliony katalogów domowych i UID (z powodu usterki skryptowej). Dlatego żadna z obecnych odpowiedzi nie działa. Test, który działa dla mnie, polega na sprawdzeniu, czy użytkownik ma prawidłową powłokę logowania. Prawidłowa powłoka jest wymieniona w /etc/shells. Najprostsza forma:

getent passwd | grep -wFf /etc/shells

Plik może zawierać komentarze (lub puste linie), więc może być konieczne ich odfiltrowanie:

getent passwd | grep -wFf <(grep '^/' /etc/shells)
muru
źródło
+1 To może być najsolidniejsze z dotychczas zaproponowanych podejść. Chociaż ma tę wadę, że pokazuje root(co prawdopodobnie nie powinno być uważane za użytkownika), ponieważ ludzie zwykle rootują tymczasowo i do określonych celów, zamiast używać go do swojej zwykłej pracy), wydaje się, że najmniej prawdopodobne jest, że zawiedzie jakikolwiek większy sposób. Metody w innych odpowiedzi (w tym moje) może nie, w zależności od sposobu, jeśli katalogi domowe nie są /home, inne śmieci jest w /home, UID są dziwne, czy system nie korzysta z DM. Ta odpowiedź działa całkiem dobrze we wszystkich tych scenariuszach.
Eliah Kagan
1

W systemach buntu zwykli użytkownicy (tj. Użytkownicy) mają identyfikatory UID zaczynające się od 1000, które są im przypisywane sekwencyjnie przy pierwszym tworzeniu ich kont. Wszystko sprowadza się do tego, że pierwsze konto utworzone w systemie buntu ma identyfikator UID wynoszący 1000. Kolejne utworzone konto ma identyfikator UID 1001. I tak dalej.

Tak więc, moim zdaniem, najprostszym sposobem wylistowania wszystkich kont użytkowników obecnych w systemie jest sprawdzenie, czy trzecia kolumna w /etc/passwdpliku zawierającym UID użytkownika jest większa lub równa 1000 i mniejsza niż, powiedzmy, 2000 (jest mało prawdopodobne, aby typowy komputer stacjonarny miał więcej niż tysiąc kont użytkowników, nie sądzisz?):

$ awk -F$':' '{ if ($3 >= 1000 && $3 < 2000) print $1; }' /etc/passwd
Misza
źródło
Dzięki za wyjaśnienie szczegółów Oli. Musisz także odfiltrować nobody. =)
anatolij techtonik
1
Nie musisz tego robić, ponieważ nikt nie ma identyfikatora UID 65534, a zatem jest automatycznie odfiltrowywany jak wszystkie inne nieludzkie konta użytkowników.
misha