Como posso listar todos os usuários humanos que eu criei? Eu tentei cat /etc/passwd
e apenas lista muitas coisas.
Como posso listar todos os usuários humanos que eu criei? Eu tentei cat /etc/passwd
e apenas lista muitas coisas.
Respostas:
Os usuários humanos têm UIDs a partir de 1000, para que você possa usar esse fato para filtrar os não humanos:
cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1
Isso corta o primeiro (nome de usuário) e o terceiro (UID) campos delimitados por dois pontos /etc/passwd
, depois filtra as linhas resultantes que terminam com dois pontos e quatro dígitos, depois corta o primeiro campo (nome de usuário), deixando-o com uma lista de usuários com UIDs entre 1000 e 9999.
Se você tiver mais de nove mil usuários em seu sistema, isso falhará - mas é necessário restringir o resultado a UIDs de quatro dígitos para não capturar nobody
(UID 65534).
Isso faz praticamente o que a resposta aceita faz, apenas em um comando, em vez de três:
awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd
E graças a Karel nos comentários, o nobody
usuário também é filtrado.
Eu pessoalmente gosto de usar apenas:
ls /home
É certo que essa não é uma lista de usuários, mas uma lista de seus diretórios pessoais. Atualmente, os usuários humanos existentes no sistema terão diretórios pessoais /home
, mas você também pode ver os diretórios pessoais de usuários anteriores que foram removidos.
Isso funciona para os meus propósitos e pode funcionar para os seus também. Por exemplo, se você deseja excluir uma conta de usuário que não existe mais ( nonexistent-user
) e executar o comando
sudo deluser nonexistent-user
apenas informará que esse usuário não existe.
/home
(que não é vinculado a /home
) do que um usuário humano tenha um UID abaixo de 1000 (afinal, esse é o método mais comum para impedir que um gerente de exibição liste um usuário na tela de login, que às vezes pode ser feito para um usuário humano). A única desvantagem relativamente menor aqui é que lost+found
será listada em sistemas com /home
partições separadas .
useradd --no-create-home username
?
useradd --no-create-home
- o diretório inicial pode já existir ou ser criado logo em seguida - mas o ls /home
método funciona bem nesses casos.
Embora possa parecer uma idéia clara, na verdade há ambiguidade no significado de usuário humano . Uma conta de usuário é ocultada deliberadamente da tela de login porque é usada apenas para fins especializados (mas humanos), um usuário humano? E o ubuntu
usuário (UID 999) no CD ao vivo? E as contas de convidado no Ubuntu são criadas on-the-fly e destruídas após o logout; eles são usuários humanos? Mais exemplos podem ser criados.
Portanto, é adequado que várias respostas não equivalentes tenham sido fornecidas. A solução de Saige Hamblin para executar ls /home
é o que as pessoas realmente fazem e, a menos que você esteja escrevendo um script, provavelmente deve usá-lo.
ls /home
mais robustoMas talvez você tenha usuários que foram removidos, mas cujos diretórios pessoais ainda existem /home
, e evite listá-los. Ou talvez por algum outro motivo, você deve garantir que apenas as entradas /home
correspondentes a contas reais sejam listadas.
Nesse caso, sugiro passando os nomes de tudo em /home
que getent
(para recuperar as passwd
entradas de usuários com esses nomes), apenas o campo de nome de usuário, em seguida, isolado e display (com grep
, sed
ou awk
, de acordo com 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 $1}'
Isso deve funcionar bem, pois você não deve ter contas de usuário com espaços em branco ou caracteres de controle em seus nomes; não pode, sem reconfigurar o Ubuntu para permitir ; e se o fizer, você terá problemas maiores. Portanto, os problemas usuais com a análise ls
são inaplicáveis. Mas mesmo que esteja tudo bem aqui, se você considerar substituições de comando com ls
esteticamente desagradável 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 $1}'
Eles não acomodam espaços em branco nem caracteres de controle. Eu os forneço apenas porque $(ls /home)
parece errado, mesmo quando está certo, e, assim, atrapalha muitos usuários da maneira errada. Na maioria das situações, existem boas e reais razões para evitar a análisels
e, nessas situações, a análise basename -a
geralmente é apenas um pouco menos ruim. Nessa situação, no entanto, devido à limitação de quais caracteres podem ocorrer praticamente nos nomes de usuários , os dois estão bem.
Uso getent
principalmente porque ele aceita nomes de usuário como argumentos para restringir sua saída, mas também porque é um pouco mais universal do que examinar /etc/passwd
diretamente, caso as instalações de autenticação e o banco de dados de senhas sejam fornecidos pelos serviços de rede.
Esse método tem o benefício adicional de ls /home
que, em sistemas com uma /home
partição separada , lost+found
geralmente aparece na saída de ls /home
.
lost+found
só aparecerá se houver um usuário (humano ou não) chamado lost+found
, o que é improvável.ls /home
- você sabe que não tem um usuário humano chamado lost+found
.Raramente, esse método (em qualquer uma das variações acima) produzirá resultados insatisfatórios:
/home
ou não existir , isso sugere, mas não implica que a conta não deva ser considerada um usuário humano. Este método lista apenas os usuários quando existe um diretório com o mesmo nome /home
./home
ninguém e eles têm o mesmo nome que um usuário não humano existente - ou consistem em palavras separadas por espaço em branco, um ou mais deles têm o mesmo nome como usuário não humano existente - alguns usuários não humanos podem ser incluídos na saída. getent
invocações separadas , portanto, a divisão de palavras não produz resultados espúrios. Mas a complexidade não é garantida; fundamentalmente, se você usar /home
como algo diferente de um local para os diretórios pessoais dos usuários, esse método será não produza uma saída confiável.)Se você optar por um método que verifique os IDs de usuário para garantir que eles estejam no intervalo provável de contas que representam seres humanos, como na resposta aceita ou na resposta de Oli , sugiro isso por uma questão de brevidade:
getent passwd | grep -oP '^[^:]+(?=:x:\d{4}:)'
Isso usa uma expressão regular Perl ( -P
) para mostrar:
^
) que não contém :
s ( [^:]+
) - este é o primeiro campo, assim como :
o separador de campos empasswd
(?=
)
) o campo de senha x
- sempre deve ser x
, pois no Ubuntu os hashes de senha são armazenados no shadow
banco de dados, não no passwd
banco de dados legível pelo mundo:\d{4}:
).Essa é, portanto, uma variante significativamente mais curta e um pouco mais simples da técnica na resposta aceita . (A técnica descrita lá também funciona bem e tem o benefício de ser portátil para sistemas não-GNU / Linux grep
que não suportam -P
.)
Se você deseja acomodar UIDs muito altos e procurar nobody
explicitamente, pode usar o método na resposta de Oli . Você pode considerar, no entanto, se usuários com UIDs muito altos realmente devem ser considerados humanos, ou se é mais provável que sejam outros usuários não humanos para fins especiais (como nobody
). Na prática, esses usuários - além de - nobody
são incomuns, então, na verdade, essa é uma decisão de sua parte.
Um possível comprometimento é listar usuários no intervalo de UIDs que estão sendo atribuídos a usuários recém-criados que não são do "sistema". Você pode verificar isso emadduser.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<$3 && $3<30000 {print $1}'
basename
é feio. Não é melhor que ls
. A principal razão pela qual não analisamos é que é um trabalho que pode ser feito por outras ferramentas de maneira muito mais segura e limpa, sem estilo. Neste caso, o shell: cd /home; getent passwd *
.
ls
geralmente é sobre estilo. O segundo ponto sobre "resultados insatisfatórios" abordou a questão, mas aparece em uma seção posterior. Eu reformulei para esclarecer por que a análise ls
é apropriada nessa situação . Embora cd /home; getent passwd *
assuma uma forma geralmente indicativa de uma abordagem mais sólida, eu a evitei para não levar os leitores a acreditar que o conteúdo dos /home
diretórios, com entradas adicionadas estranhas que não correspondam a usuários reais, ainda pudesse ser de alguma forma considerado como um guia para o que existem usuários.
TL; DR : somente usuários humanos têm SystemAccount = false
Uma outra maneira é listar a saída enquanto ignora o root ls /var/lib/AccountsService/users/ | grep -v root
. Agora, existe uma peculiaridade - gdm, uma tela de boas-vindas / login (ou, mais formalmente, gerenciador de desktop) também é listada como usuário. Então, apenas a partir da lista, não podemos dizer se o gdm é humano ou não.
Uma abordagem mais eficiente e correta é pesquisar os arquivos nessa pasta e descobrir quais usuários estão listados como tendo SystemAccount=false
. O one-liner abaixo alcança que
grep SystemAccount=false /var/lib/AccountsService/users/* | awk -F '/' '{gsub(":","/");print $6}'
mini.iso
e sem gerenciadores de tela ou X11 instalado), tenho uma conta de usuário humano - ainda /var/lib/AccountsService/users
é um diretório vazio. Eu espero que isso também não funcione em uma instalação pronta do Ubuntu Server. Além disso, quando isso funciona, o faz sob uma noção um tanto restritiva do que torna uma conta de usuário "humana": tornar um usuário com useradd
, mesmo sem --system
, não cria um arquivo AccountsService/users
.
Juntando-me à parte, supervisiono os sistemas de rede usando LDAP, tendo diretórios /home
pessoais externos e UIDs (devido a uma falha de script) na casa dos milhões. Nenhuma das respostas atuais, portanto, funciona. O teste que funciona para mim é verificar se o usuário possui um shell de login válido. Um shell válido é aquele listado em /etc/shells
. A forma mais simples:
getent passwd | grep -wFf /etc/shells
O arquivo pode conter comentários (ou linhas vazias); portanto, pode ser necessário filtrá-los:
getent passwd | grep -wFf <(grep '^/' /etc/shells)
root
(que provavelmente não deve ser considerado um usuário humano, uma vez que os humanos geralmente se tornam raiz temporariamente e para fins específicos, em vez de usá-lo em seu trabalho regular), parece que é o menos provável que isso ocorra de qualquer maneira importante. Os métodos em outras respostas (incluindo as minhas) podem falhar, dependendo do método, se os diretórios pessoais não estiverem em/home
, outros tipos de lixo é no /home
, UIDs são estranhos, ou o sistema não usa um DM. Essa resposta funciona muito bem em todos esses cenários.
Nos sistemas buntu, usuários regulares (usuários humanos, ou seja) têm UIDs começando com 1000, que são atribuídos sequencialmente a eles quando suas contas são criadas. O que tudo isso se resume é que a primeira conta criada em um sistema Ubuntu possui um UID de 1000. A próxima criada tem um UID de 1001. E assim por diante.
Portanto, na minha opinião, a maneira mais simples de listar todas as contas de usuários humanos presentes no sistema é verificar se a terceira coluna no /etc/passwd
arquivo que contém o UID do usuário é maior ou igual a 1000 e menor que, digamos, 2000 (é muito improvável que um PC de mesa típico tenha mais de mil contas de usuário, não acha?):
$ awk -F$':' '{ if ($3 >= 1000 && $3 < 2000) print $1; }' /etc/passwd
nobody
. =)