Embora possa parecer uma ideia clara, na verdade há ambigüidade no significado de usuário humano . Uma conta de usuário é deliberadamente oculta da tela de login porque é usada apenas para fins especializados (mas por humanos) um usuário humano? Como sobre o usuário ubuntu
(UID 999) no CD ao vivo? E contas de convidados no Ubuntu são criadas on-the-fly e destruídas após o logout; são usuários humanos? Mais exemplos podem ser inventados.
Portanto, é apropriado que várias respostas não equivalentes tenham sido dadas. A solução de Saige Hamblin de executar ls /home
é o que as pessoas realmente fazem, e a menos que você esteja escrevendo um script, você provavelmente deveria usar isso.
Tornando ls /home
mais robusto
Mas talvez você tenha usuários que foram removidos, mas cujos diretórios pessoais ainda existem em /home
, e você deve evitar listá-los. Ou, talvez, por algum outro motivo, você deve garantir que apenas as entradas em /home
que correspondem às contas reais sejam listadas.
Nesse caso, sugiro passar os nomes de tudo em /home
para getent
(para recuperar as entradas passwd
dos usuários com esses nomes), isole e exiba apenas o campo nome de usuário (com grep
, sed
ou awk
, conforme sua preferência ). Qualquer um deles fará:
getent passwd $(ls /home) | grep -o '^[^:]*'
getent passwd $(ls /home) | sed 's/:.*//'
getent passwd $(ls /home) | awk -F: '{print }'
Isso deve funcionar bem, já que você não deve ter contas de usuário com espaço em branco ou controlar caracteres em seus nomes; não pode, sem reconfigurar o Ubuntu para permitir ; e se você fizer isso, você tem problemas maiores. Assim, os problemas comuns com a análise de ls
são inaplicáveis. Mas mesmo que esteja tudo bem aqui, se você considerar as substituições de comandos com ls
esteticamente desagradáveis ou apenas um mau hábito, você pode preferir:
getent passwd $(basename -a /home/*) | grep -o '^[^:]*'
getent passwd $(basename -a /home/*) | sed 's/:.*//'
getent passwd $(basename -a /home/*) | awk -F: '{print }'
Eles também não acomodam espaços em branco ou controlam caracteres. Eu os forneço apenas porque $(ls /home)
parece errado, mesmo quando está certo, e assim atrapalha muitos usuários. Na maioria das situações, há razões reais e boas para evitar a análise de ls
e, nessas situações, a análise de basename -a
geralmente é apenas muito ligeiramente menos ruim. Nessa situação, no entanto, devido à limitação de quais caracteres podem praticamente ocorrer em nomes de usuário, eles estão bem.
Explicação, benefícios e desvantagens
Eu uso getent
principalmente porque aceita nomes de usuários como argumentos para restringir sua saída, mas também porque é um pouco mais universal do que examinar /etc/passwd
diretamente, caso os recursos de autenticação e o banco de dados de senha sejam fornecidos pelos serviços de rede. / p>
Este método tem o benefício adicional sobre ls /home
que, em sistemas com uma partição /home
separada, lost+found
geralmente aparece na saída de ls /home
.
- Com o método mais robusto apresentado acima,
lost+found
só aparecerá se houver um usuário (humano ou não) chamado lost+found
, o que é improvável.
- Mas se você estiver digitando comandos de forma interativa, em vez de escrever um script,
ls /home
é bom - você sabe que não tem um usuário humano chamado lost+found
.
Infrequentemente, esse método (em qualquer uma das variações acima) produzirá resultados insatisfatórios:
- Se o diretório pessoal de um usuário existir fora de
/home
ou nada, isso sugere, mas não implica que a conta não deva ser considerada como representando um usuário humano. Esse método lista apenas os usuários quando há um diretório com o mesmo nome em /home
.
- Se você criou diretórios adicionais em
/home
que não são o diretório pessoal de qualquer pessoa, e eles têm o mesmo nome de um usuário não humano existente - ou consistem em palavras separados por espaço em branco, um ou mais dos quais tem o mesmo nome de um usuário não humano existente - então alguns usuários não humanos podem ser incluídos na saída.
(Esse método pode ser implementado com um loop e separar invocações de getent
, então divisão de palavras não produz resultados espúrios. a complexidade não é garantida; fundamentalmente, se você usar /home
como algo diferente de um local para os diretórios iniciais dos usuários, esse método não produzirá resultados confiáveis.
Fazendo a verificação de UIDs mais simples
Se você decidir usar um método que verifique os IDs dos usuários para garantir que eles estejam no intervalo provável para contas que representam seres humanos, como em a resposta aceita ou a resposta de Oli , então eu sugiro isso por brevidade :
getent passwd | grep -oP '^[^:]+(?=:x:\d{4}:)'
Isso usa uma expressão regular Perl ( -P
) para mostrar :
- texto no início de uma linha (
^
) sem :
s ( [^:]+
) - este é o primeiro campo, pois :
é o separador de campo em passwd
- que precede, mas não inclui (
(?=
)
) o campo de senha x
- deve ser sempre x
, já que os hashes de senha do Ubuntu são armazenados no shadow
, não o banco de dados passwd
legível para o mundo
- e um campo UID com exatamente 4 dígitos (
:\d{4}:
).
Esta é, portanto, uma variante significativamente mais curta e mais simples da técnica na resposta aceita . (A técnica descrita também funciona bem, e tem o benefício de ser portável para sistemas não-GNU / Linux, cujo grep
não suporta -P
.)
Reconsiderando o intervalo UID "Humano"
Se você deseja acomodar UIDs muito altos e verificar nobody
explicitamente, você pode usar o método em resposta de Oli . Você pode querer considerar, no entanto, se os usuários com UIDs muito altos devem ser realmente considerados humanos, ou se eles são mais propensos a ser algum outro usuário não-humano de propósito especial (como nobody
). Na prática, esses usuários - além de nobody
- são incomuns, então, na verdade, esse é um julgamento de sua parte.
Um compromisso possível é listar os usuários no intervalo de UIDs que estão sendo atribuídos a usuários recém-criados e não "sistema". Você pode verificar esta em adduser.conf
:
$ grep -E '^(FIRST|LAST)_UID' /etc/adduser.conf
FIRST_UID=1000
LAST_UID=29999
Aqui estão duas maneiras de listar usuários cujos UIDs variam de 1000 a 29999:
getent passwd | grep -oP '^[^:]+(?=:x:[12]?\d{4}:)'
getent passwd | awk -F: '999< && <30000 {print }'