¿Cómo puedo enumerar todos los usuarios humanos que he creado? Lo he intentado cat /etc/passwd
y solo enumera muchas cosas.
¿Cómo puedo enumerar todos los usuarios humanos que he creado? Lo he intentado cat /etc/passwd
y solo enumera muchas cosas.
Respuestas:
Los usuarios humanos tienen UID que comienzan en 1000, por lo que puede usar ese hecho para filtrar a los no humanos:
cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1
Esto corta los campos delimitados por dos puntos primero (nombre de usuario) y tercero (UID) /etc/passwd
, luego filtra las líneas resultantes que terminan con dos puntos y cuatro dígitos, luego corta el primer campo (nombre de usuario) de ese, dejándolo con una lista de usuarios con UID entre 1000 y 9999.
Si tiene más de nueve mil usuarios en su sistema, esto fallará, pero es necesario restringir el resultado a UID de 4 dígitos para no detectarlo nobody
(UID 65534).
Esto hace más o menos lo que hace la respuesta aceptada , solo en un comando en lugar de tres:
awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd
Y gracias a Karel en los comentarios, el nobody
usuario también se filtra.
Personalmente me gusta usar solo:
ls /home
Es cierto que esta no es una lista de usuarios, sino una lista de sus directorios de inicio. Los usuarios humanos actualmente existentes en el sistema tendrán directorios de inicio /home
, pero también puede ver los directorios de inicio de los usuarios anteriores que fueron eliminados.
Esto funciona para mis propósitos y puede funcionar para los suyos también. Por ejemplo, si está buscando eliminar una cuenta de usuario que ya no existe ( nonexistent-user
) y ejecutar el comando
sudo deluser nonexistent-user
solo le dirá que este usuario no existe.
/home
(que no esté vinculado a un enlace simbólico /home
) que un usuario humano que tenga un UID de menos de 1000 (después de todo, este es el método más común para evitar que un administrador de visualización aparezca en la lista un usuario en la pantalla de inicio de sesión, que a veces puede hacerse para un usuario humano). La única desventaja relativamente menor aquí es que lost+found
se enumerará en sistemas con /home
particiones separadas .
useradd --no-create-home username
?
useradd --no-create-home
directorio de inicio podría ya existir o podría crearse poco después, pero el ls /home
método funciona bien para esos casos.
Si bien puede parecer una idea clara, en realidad existe una ambigüedad en el significado del usuario humano . ¿Se oculta deliberadamente una cuenta de usuario de la pantalla de inicio de sesión porque solo se usa para fines especializados (pero por humanos) un usuario humano? ¿Qué tal el ubuntu
usuario (UID 999) en el CD en vivo? Y las cuentas de invitado en Ubuntu se crean sobre la marcha y se destruyen después de cerrar sesión; son usuarios humanos? Se podrían idear más ejemplos.
Por lo tanto, es apropiado que se hayan dado múltiples respuestas no equivalentes. La solución de ejecución de Saige Hamblinls /home
es lo que la gente realmente hace, y a menos que esté escribiendo un script, probablemente debería usar eso.
ls /home
más robustoPero quizás tenga usuarios que han sido eliminados, pero cuyos directorios principales todavía existen /home
, y debe evitar enumerarlos. O tal vez por alguna otra razón, debe asegurarse de que solo /home
se enumeren las entradas que corresponden a cuentas reales.
En ese caso, sugiero pasar los nombres de todo lo /home
que getent
(para recuperar las passwd
entradas de los usuarios con los nombres), sólo el campo nombre de usuario a continuación, aislar y visualizar (con grep
, sed
o awk
, según su preferencia). Cualquiera de estos hará:
getent passwd $(ls /home) | grep -o '^[^:]*'
getent passwd $(ls /home) | sed 's/:.*//'
getent passwd $(ls /home) | awk -F: '{print $1}'
Esto debería funcionar bien, ya que no debería tener cuentas de usuario con espacios en blanco o caracteres de control en sus nombres; no puede, sin reconfigurar Ubuntu para permitirlo ; y si lo haces, tienes mayores problemas. Por lols
tanto, los problemas habituales con el análisis no son aplicables. Pero a pesar de que está realmente bien aquí, si considera las sustituciones de comandos con ls
desagrado estético o simplemente un mal hábito, puede preferir:
getent passwd $(basename -a /home/*) | grep -o '^[^:]*'
getent passwd $(basename -a /home/*) | sed 's/:.*//'
getent passwd $(basename -a /home/*) | awk -F: '{print $1}'
Estos tampoco admiten espacios en blanco ni caracteres de control. Los proporciono solo porque se $(ls /home)
ve mal incluso cuando es correcto y, por lo tanto, afecta a muchos usuarios de la manera incorrecta. En la mayoría de las situaciones, existen buenas razones reales para evitar el análisisls
, y en esas situaciones, el análisis basename -a
suele ser solo un poco menos malo. En esta situación, sin embargo, debido a la limitación sobre qué caracteres pueden aparecer prácticamente en los nombres de usuario , ambos están bien.
Lo uso getent
principalmente porque acepta nombres de usuario como argumentos para restringir su salida, pero también porque es un poco más universal que examinar /etc/passwd
directamente, en caso de que los servicios de red proporcionen servicios de autenticación y la base de datos de contraseñas.
Este método tiene la ventaja adicional de ls /home
que, en sistemas con una /home
partición separada , lost+found
generalmente aparece en la salida de ls /home
.
lost+found
solo aparecerá si se llama a un usuario (humano o no) lost+found
, lo cual es poco probable.ls /home
está bien , sabe que no tiene un usuario humano llamado lost+found
.Con poca frecuencia, este método (en cualquiera de las variaciones anteriores) producirá resultados insatisfactorios:
/home
, o no existe , esto sugiere, pero no implica, que la cuenta no debe considerarse como un usuario humano. Este método solo enumera los usuarios cuando hay un directorio con el mismo nombre /home
./home
que no son en realidad el directorio de inicio de nadie, y tienen el mismo nombre que un usuario no humano existente, o consisten en palabras separadas por espacios en blanco, uno o más de los cuales tienen el mismo nombre como un usuario no humano existente, entonces algunos usuarios no humanos pueden incluirse en la salida. getent
invocaciones separadas , por lo que la división de palabras no produce resultados espurios. Pero la complejidad no está garantizada; fundamentalmente, si utiliza /home
algo más que un lugar para los directorios de inicio de los usuarios, este método será no produce resultados confiables)Si decide utilizar un método que verifica las ID de los usuarios para asegurarse de que estén en el rango probable de cuentas que representan seres humanos, como en la respuesta aceptada o la respuesta de Oli , sugiero esto por brevedad:
getent passwd | grep -oP '^[^:]+(?=:x:\d{4}:)'
Esto usa una expresión regular Perl ( -P
) para mostrar:
^
) que no contiene :
s ( [^:]+
): este es el primer campo, al igual :
que el separador de campo enpasswd
(?=
)
) el campo de contraseña x
: siempre debe serlo x
, ya que en Ubuntu los hashes de contraseña se almacenan en la shadow
base de datos, no en la base de passwd
datos legible en todo el mundo:\d{4}:
).Por lo tanto, esta es una variante significativamente más corta y algo más simple de la técnica en el respuesta aceptada . (La técnica descrita allí también funciona bien, y tiene la ventaja de ser portátil para sistemas que grep
no son GNU / Linux y que no son compatibles -P
).
Si desea acomodar UID muy altos y verificar nobody
explícitamente, puede usar el método en la respuesta de Oli . Sin embargo, es posible que desee considerar si los usuarios con UID muy altos realmente deberían considerarse humanos, o si es más probable que sean otros usuarios no humanos con fines especiales (como nobody
). En la práctica, tales usuarios, además, nobody
son poco comunes, por lo que realmente es una decisión de tu parte.
Un posible compromiso es enumerar a los usuarios en el rango de UID que en realidad se están asignando a usuarios recién creados que no son del "sistema". Puedes verificar esto enadduser.conf
:
$ grep -E '^(FIRST|LAST)_UID' /etc/adduser.conf
FIRST_UID=1000
LAST_UID=29999
Aquí hay dos formas de enumerar los usuarios cuyos UID varían de 1000 a 29999:
getent passwd | grep -oP '^[^:]+(?=:x:[12]?\d{4}:)'
getent passwd | awk -F: '999<$3 && $3<30000 {print $1}'
basename
es feo. No es mejor que ls
. La razón principal por la que no analizamos ls es que es un trabajo que pueden realizar otras herramientas de manera mucho más segura y limpia, no con estilo. En este caso, el Shell: cd /home; getent passwd *
.
ls
generalmente se trata de estilo. El segundo punto sobre "resultados insatisfactorios" cubrió el problema, pero aparece en una sección posterior. Volví a redactar para aclarar por qué el análisis ls
es apropiado en esta situación . Aunque cd /home; getent passwd *
adopte una forma a menudo indicativa de un enfoque más sólido, lo he evitado para no llevar a los lectores a creer que el contenido de los /home
directorios, con entradas añadidas extrañas que no corresponden a usuarios reales, podría de alguna manera ser considerado como una guía de lo que los usuarios existen
TL; DR : solo usuarios humanos tienen SystemAccount = false
Otra forma es enumerar la salida de mientras se ignora la raíz ls /var/lib/AccountsService/users/ | grep -v root
. Ahora, hay una peculiaridad: gdm, una pantalla de bienvenida / inicio de sesión (o más formalmente un administrador de escritorio) también aparece como usuario. Entonces, solo de la lista no podemos decir si gdm es humano o no.
Un enfoque más eficiente y correcto es revisar los archivos en esa carpeta y descubrir qué usuarios están en la lista SystemAccount=false
. El bramido de una línea logra que
grep SystemAccount=false /var/lib/AccountsService/users/* | awk -F '/' '{gsub(":","/");print $6}'
mini.iso
y sin administradores de pantalla o X11 instalado), tengo una cuenta de usuario humano, pero /var/lib/AccountsService/users
es un directorio vacío. Espero que esto no funcione de manera similar en una instalación de Ubuntu Server lista para usar. Además, cuando esto funciona, lo hace bajo una noción algo restrictiva de lo que hace que una cuenta de usuario sea "humana": hacer que un usuario con useradd
, incluso sin --system
, no cree un archivo AccountsService/users
.
Al unirme a la fiesta, superviso los sistemas de red que utilizan LDAP, que tienen /home
millones de directorios externos y UID (debido a una falla en las secuencias de comandos). Ninguna de las respuestas actuales, por lo tanto, funciona. La prueba que funciona para mí es verificar si el usuario tiene un shell de inicio de sesión válido. Un shell válido es uno que se enumera en /etc/shells
. La forma más simple:
getent passwd | grep -wFf /etc/shells
El archivo puede contener comentarios (o líneas vacías), por lo que es posible que tenga que filtrarlos:
getent passwd | grep -wFf <(grep '^/' /etc/shells)
root
(que probablemente no debería considerarse un usuario humano, ya que los humanos generalmente se convierten en root temporalmente y para fines específicos, en lugar de usarlo para su trabajo regular), parece que es menos probable que falle Cualquier forma importante. Los métodos en otras respuestas (incluida la mía) pueden fallar, dependiendo del método, si no son los directorios de inicio en /home
, otro tipo de basura es en /home
, UID son extraños, o el sistema no utiliza un DM. Esta respuesta funciona bastante bien en todos esos escenarios.
En los sistemas buntu, los usuarios habituales (es decir, usuarios humanos) tienen UID que comienzan con 1000 que se les asignan secuencialmente cuando se crean sus cuentas por primera vez. Todo esto se reduce a que la primera cuenta creada en un sistema buntu tiene un UID de 1000. La siguiente cuenta creada tiene un UID de 1001. Y así sucesivamente.
Entonces, la forma más simple de enumerar todas las cuentas de usuarios humanos presentes en el sistema, en mi opinión, es verificar si la tercera columna en el /etc/passwd
archivo que contiene el UID del usuario es mayor o igual a 1000 y menor que, digamos, 2000 (es muy poco probable que una PC de escritorio típica tenga más de mil cuentas de usuario, ¿no cree?):
$ awk -F$':' '{ if ($3 >= 1000 && $3 < 2000) print $1; }' /etc/passwd
nobody
. =)