Elencare tutti gli utenti umani


19

Come posso elencare tutti gli utenti umani che ho creato? Ho provato cat /etc/passwded elenca solo un sacco di cose.

Risposte:


18

Gli utenti umani hanno UID a partire da 1000, quindi puoi usare questo fatto per filtrare i non umani:

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

Ciò taglia il primo (nome utente) e il terzo (UID) campi delimitati da due punti /etc/passwd, quindi filtra le righe risultanti che terminano con due punti e quattro cifre, quindi taglia il primo campo (nome utente) da quello, lasciandoti con un elenco di utenti con UID tra 1000 e 9999.

Se hai più di 9.000 utenti nel tuo sistema, questo fallirà, ma è necessario limitare il risultato a UID a 4 cifre per non catturare nobody(UID 65534).


15

Questo fa praticamente quello che fa la risposta accettata , solo in un comando anziché in tre:

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

E grazie a Karel nei commenti, l' nobodyutente viene anche filtrato.


@karel Sì, forse. Invece di filtrare per UID, sto filtrando esplicitamente quel nome utente. Potrebbe esserci un motivo per avere un utente legittimo con un UID così alto ... Chissà;)
Oli

9

Personalmente mi piace usare solo:

ls /home

Certamente questo non è un elenco di utenti ma piuttosto un elenco delle loro home directory. Attualmente gli utenti umani esistenti sul sistema avranno home directory /home, ma potresti vedere anche le home directory degli utenti precedenti che sono state rimosse.

Questo funziona per i miei scopi e può funzionare anche per i tuoi. Ad esempio, se stai cercando di eliminare un account utente che non risulta più esistente ( nonexistent-user) ed esegui il comando

sudo deluser nonexistent-user

ti dirà semplicemente che questo utente non esiste.


+1 In questo modo è semplice, è ciò che gli utenti più esperti farebbero effettivamente, e penso che non sia meno robusto dei metodi che controllano una gamma di UID. Sembra meno probabile che un utente umano disponga di una home directory all'esterno /home(a cui non è associato un collegamento simbolico /home) rispetto a un utente umano che abbia un UID inferiore a 1000 (dopo tutto, questo è il metodo più comune per mantenere un display manager dall'elenco un utente nella schermata di accesso, che a volte può essere fatto per un utente umano). L'unico svantaggio relativamente minore qui è che lost+foundsaranno elencati su sistemi con /homepartizioni separate .
Eliah Kagan,

Piccolo problema, però: cosa succede se l'utente è stato creato con useradd --no-create-home username?
Sergiy Kolodyazhnyy

@Serg Penso che dipenda dall'ambiguità intrinseca nella descrizione del problema. Un account senza home directory rappresenta davvero un utente umano? In pratica, tali account sono di solito - anche se certamente non sempre - utilizzati per attività altamente specializzate (in genere da persone con i propri account separati) o per gli utenti che intendono accedere al sistema solo attraverso servizi specifici e limitati. Naturalmente c'è un altro caso d'uso per useradd --no-create-home- la home directory potrebbe già esistere o potrebbe essere creata poco dopo - ma il ls /homemetodo funziona bene per quei casi.
Eliah Kagan,

4

Sebbene possa sembrare un'idea chiara, in realtà c'è ambiguità nel significato dell'utente umano . Un account utente è deliberatamente nascosto dalla schermata di accesso perché è utilizzato solo per scopi specializzati (ma da esseri umani) un utente umano? Che ne dici ubuntudell'utente (UID 999) sul CD live? E gli account guest in Ubuntu vengono creati al volo e distrutti dopo il logout; sono utenti umani? Altri esempi potrebbero essere escogitati.

Pertanto, è opportuno che siano state fornite risposte multiple e non equivalenti. La soluzione di corsa di Saige Hamblinls /home è ciò che la gente fa realmente e, a meno che tu non stia scrivendo una sceneggiatura, probabilmente dovresti semplicemente usarla.

Rendendo ls /homepiù robusto

Ma forse hai utenti che sono stati rimossi, ma le cui home directory sono ancora presenti /homee devi evitare di elencarli. O forse per qualche altro motivo è necessario assicurarsi /homeche siano elencate solo le voci corrispondenti a conti reali.

In tal caso, vi suggerisco di passare i nomi di tutto /homeper getent(per recuperare le passwdvoci degli utenti con quei nomi), solo il campo nome utente quindi isolare e display (con grep, sedo awk, secondo la vostra preferenza). Ognuno di questi farà:

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

Questo dovrebbe funzionare bene, poiché non dovresti avere account utente con spazi bianchi o caratteri di controllo nei loro nomi; impossibile, senza riconfigurare Ubuntu per consentirlo ; e se lo fai, hai problemi più grandi. Quindi i soliti problemi con l'analisi lssono inapplicabili. Ma anche se qui va davvero bene, se consideri le sostituzioni di comandi con lsesteticamente spiacevole o solo una cattiva abitudine, potresti preferire:

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

Questi non possono contenere nemmeno spazi bianchi o caratteri di controllo. Li fornisco solo perché $(ls /home)sembra sbagliato anche quando è giusto, e quindi strofina molti utenti nel modo sbagliato. Nella maggior parte delle situazioni, ci sono dei veri e buoni motivi per evitare l'analisils , e in quelle situazioni di basename -asolito l' analisi è solo leggermente meno grave. In questa situazione, tuttavia, a causa della limitazione di ciò che i personaggi possono praticamente apparire nei nomi utente , vanno entrambi bene.

Spiegazione, vantaggi e svantaggi

Uso getentprincipalmente perché accetta i nomi utente come argomenti per limitarne l'output, ma anche perché è leggermente più universale rispetto all'esame /etc/passwddiretto, nel caso in cui i servizi di rete forniscano servizi di autenticazione e il database delle password.

Questo metodo ha l'ulteriore vantaggio rispetto a ls /homequello, sui sistemi con una /homepartizione separata , di lost+foundsolito appare nell'output di ls /home.

  • Con il metodo più robusto presentato sopra, lost+foundapparirà solo se si verifica un utente (umano o meno) chiamato lost+found, il che è improbabile.
  • Ma se stai entrando comandi in modo interattivo, piuttosto che scrivere una sceneggiatura, ls /homeè fine-- si sa non si dispone di un utente umano chiamato lost+found.

Raramente, questo metodo (in una qualsiasi delle varianti precedenti) produrrà risultati insoddisfacenti:

  • Se la home directory di un utente esiste al di fuori /homeo non lo è affatto, ciò suggerisce ma non implica che l'account non debba essere considerato come un utente umano. Questo metodo elenca gli utenti solo quando è presente una directory con lo stesso nome /home.
  • Se hai creato directory aggiuntive /homeche in realtà non sono la home directory di nessuno e hanno lo stesso nome di un utente non umano esistente - o sono composte da parole separate da spazi bianchi, una o più delle quali hanno lo stesso nome come utente non umano esistente, quindi alcuni utenti non umani potrebbero essere inclusi nell'output.
    (Questo metodo può essere implementato con un ciclo e getentinvocazioni separate , quindi la suddivisione delle parole non produce risultati spuri. Ma la complessità non è giustificata; fondamentalmente, se si utilizza /homecome qualcosa di diverso da un luogo per le home directory degli utenti, questo metodo non produce risultati affidabili.)

Semplificazione del controllo UID

Se decidi di seguire un metodo che controlla gli ID utente per assicurarsi che siano nell'intervallo probabile per gli account che rappresentano gli esseri umani, come nella risposta accettata o nella risposta di Oli , suggerisco questo per brevità:

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

Questo utilizza un'espressione regolare Perl ( -P) per mostrare:

  • testo all'inizio di una riga ( ^) che non contiene :s ( [^:]+) - questo è il primo campo, così come :il separatore di campi inpasswd
  • che precede ma non include ( (?= )) il campo password x- dovrebbe sempre essere x, poiché in Ubuntu gli hash delle password sono memorizzati nel shadowdatabase, non nel passwddatabase leggibile dal mondo
  • e un campo UID composto esattamente da 4 cifre ( :\d{4}:).

Questa è quindi una variante significativamente più breve e un po 'più semplice della tecnica nella risposta accettata . (Anche la tecnica qui descritta funziona bene e ha il vantaggio di essere portabile su sistemi non GNU / Linux i cui grepnon supportano -P.)

Riconsiderando la gamma UID "umana"

Se si desidera gestire UID molto elevati e verificare nobodyesplicitamente, è possibile utilizzare il metodo nella risposta di Oli . Potresti voler considerare, tuttavia, se gli utenti con UID molto elevati dovrebbero davvero essere considerati umani, o se hanno maggiori probabilità di essere un altro utente non umano per scopi speciali (come nobody). In pratica, tali utenti - oltre a - nobodynon sono comuni, quindi in realtà questa è una richiesta di giudizio da parte tua.

Un possibile compromesso è elencare gli utenti nella gamma di UID che vengono effettivamente assegnati a utenti non "di sistema" appena creati. Puoi verificarlo inadduser.conf :

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

Ecco due modi per elencare gli utenti i cui UID vanno da 1000 a 29999:

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

Se volevi essere stilisticamente piacevole, basenameè brutto. Non è meglio di ls. Il motivo principale per cui non analizziamo è che si tratta di un lavoro che può essere svolto da altri strumenti in modo molto più sicuro e pulito, non dallo stile. In questo caso, il guscio: cd /home; getent passwd *.
muru,

Sono d'accordo con te su / home essendo inaffidabile (è inutile per me, vedi la mia risposta). Sto solo dicendo che se hai intenzione di predicare sullo stile, aspettati il ​​nitpicking.
muru,

@muru Vedo come il mio fraseggio originale potrebbe indurre in errore le persone a pensare che evitare di analizzare lsriguardi solitamente lo stile. Il secondo punto in "output non soddisfacente" ha riguardato il problema, ma appare in una sezione successiva. Ho riformulato per chiarire perché l'analisi lsè appropriata in questa situazione . Sebbene cd /home; getent passwd *abbia una forma spesso indicativa di un approccio più sano, l'ho evitato in modo da non indurre i lettori a credere che il contenuto delle /homedirectory, con strane voci aggiunte non corrispondenti agli utenti reali, possa in qualche modo essere considerato come una guida a ciò che gli utenti esistono.
Eliah Kagan,

1

TL; DR : solo gli utenti umani hanno SystemAccount = false

Un altro modo è elencare l'output di ignorando root ls /var/lib/AccountsService/users/ | grep -v root. Ora, c'è una stranezza: gdm, una schermata di benvenuto / login (o più formalmente desktop manager) è anche elencata come utente. Quindi, solo dalla lista non possiamo dire se gdm è umano o no.

Un approccio più efficiente e corretto è quello di esaminare i file in quella cartella e scoprire quali utenti sono elencati come aventi SystemAccount=false. Il soffietto a una fodera lo raggiunge

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


1
Anche se a volte utile, ciò fallisce in alcuni scenari relativamente comuni. Ad esempio, sul mio sistema Ubuntu 15.04 minimo (installato da mini.isoe senza display manager o X11 installato), ho un account utente umano - ma /var/lib/AccountsService/usersè una directory vuota. Mi aspetto che allo stesso modo non funzionerà su un'installazione predefinita di Ubuntu Server. Inoltre, quando funziona, lo fa con una nozione piuttosto restrittiva di ciò che rende un account utente "umano": rendere un utente con useradd, anche senza --system , non crea un file AccountsService/users.
Eliah Kagan,

1

Unendomi alla festa, sovrintendo a sistemi di rete che utilizzano LDAP, con directory home esterne /homee UID (a causa di un errore di scripting) a milioni. Nessuna delle risposte attuali, quindi, funziona. Il test che funziona per me sta verificando se l'utente ha una shell di accesso valida. Una shell valida è quella elencata in /etc/shells. La forma più semplice:

getent passwd | grep -wFf /etc/shells

Il file può contenere commenti (o righe vuote), quindi potrebbe essere necessario filtrarli:

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

+1 Questo potrebbe essere l'approccio più solido suggerito finora. Sebbene abbia lo svantaggio di mostrare root(che probabilmente non dovrebbe essere considerato un utente umano, dal momento che gli umani di solito diventano radice temporaneamente e per scopi specifici, piuttosto che usarlo per il loro normale lavoro), sembra che sia la meno probabilità di fallire qualsiasi modo importante. I metodi in altre risposte (compreso il mio) potrebbero non riuscire, a seconda del metodo, se le home directory non sono /home, altri rifiuti è in /home, UID sono strani, o il sistema non utilizza un DM. Questa risposta funziona abbastanza bene in tutti quegli scenari.
Eliah Kagan,

1

Sui sistemi buntu, gli utenti regolari (utenti umani, cioè) hanno UID a partire da 1000 che vengono assegnati in sequenza a loro quando i loro account vengono creati per la prima volta. Ciò che si riduce a tutto ciò è che il primo account creato su un sistema buntu ha un UID di 1000. Il successivo creato ha un UID di 1001. E così via e così via.

Quindi, il modo più semplice per elencare tutti gli account utente umani presenti sul sistema, secondo me, è verificare se la terza colonna nel /etc/passwdfile che contiene l'UID dell'utente è maggiore o uguale a 1000 e inferiore, diciamo, 2000 (è molto improbabile che un tipico PC desktop abbia più di mille account utente, non credi?):

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

Grazie per aver spiegato la risposta di Oli con i dettagli. Devi anche filtrare nobody. =)
anatoly techtonik il

1
Non è necessario perché nessuno ha un UID di 65534 e quindi viene automaticamente filtrato come tutti gli altri account utente non umani.
misha,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.