Come posso elencare tutti gli utenti umani che ho creato? Ho provato cat /etc/passwd
ed elenca solo un sacco di cose.
Come posso elencare tutti gli utenti umani che ho creato? Ho provato cat /etc/passwd
ed elenca solo un sacco di cose.
Risposte:
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).
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' nobody
utente viene anche filtrato.
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.
/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+found
saranno elencati su sistemi con /home
partizioni separate .
useradd --no-create-home username
?
useradd --no-create-home
- la home directory potrebbe già esistere o potrebbe essere creata poco dopo - ma il ls /home
metodo funziona bene per quei casi.
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 ubuntu
dell'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.
ls /home
più robustoMa forse hai utenti che sono stati rimossi, ma le cui home directory sono ancora presenti /home
e devi evitare di elencarli. O forse per qualche altro motivo è necessario assicurarsi /home
che siano elencate solo le voci corrispondenti a conti reali.
In tal caso, vi suggerisco di passare i nomi di tutto /home
per getent
(per recuperare le passwd
voci degli utenti con quei nomi), solo il campo nome utente quindi isolare e display (con grep
, sed
o 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 ls
sono inapplicabili. Ma anche se qui va davvero bene, se consideri le sostituzioni di comandi con ls
esteticamente 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 -a
solito 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.
Uso getent
principalmente perché accetta i nomi utente come argomenti per limitarne l'output, ma anche perché è leggermente più universale rispetto all'esame /etc/passwd
diretto, 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 /home
quello, sui sistemi con una /home
partizione separata , di lost+found
solito appare nell'output di ls /home
.
lost+found
apparirà solo se si verifica un utente (umano o meno) chiamato lost+found
, il che è improbabile.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:
/home
o 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
./home
che 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. getent
invocazioni separate , quindi la suddivisione delle parole non produce risultati spuri. Ma la complessità non è giustificata; fondamentalmente, se si utilizza /home
come qualcosa di diverso da un luogo per le home directory degli utenti, questo metodo non produce risultati affidabili.)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:
^
) che non contiene :
s ( [^:]+
) - questo è il primo campo, così come :
il separatore di campi inpasswd
(?=
)
) il campo password x
- dovrebbe sempre essere x
, poiché in Ubuntu gli hash delle password sono memorizzati nel shadow
database, non nel passwd
database leggibile dal mondo:\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 grep
non supportano -P
.)
Se si desidera gestire UID molto elevati e verificare nobody
esplicitamente, è 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 - nobody
non 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}'
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 *
.
ls
riguardi 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 /home
directory, con strane voci aggiunte non corrispondenti agli utenti reali, possa in qualche modo essere considerato come una guida a ciò che gli utenti esistono.
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}'
mini.iso
e 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
.
Unendomi alla festa, sovrintendo a sistemi di rete che utilizzano LDAP, con directory home esterne /home
e 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)
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.
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/passwd
file 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
nobody
. =)