pwd en Python: consulta usuarios Unix

Publicado el: 26/08/2026
Tempo de leitura: 6 minutos
A developer typing code on a laptop with a Python book beside in an office.

El módulo pwd consulta la base de cuentas de usuario en sistemas Unix. Permite localizar una cuenta por UID numérico o nombre de login y obtener datos como UID, GID primario, directorio home, shell configurado y campo descriptivo.

Aunque históricamente se conoce como “password database”, pwd no es una API de autenticación. En sistemas modernos, las credenciales suelen estar en shadow passwords, PAM, LDAP, SSSD u otro proveedor de identidad. El campo pw_passwd normalmente contiene solo x, * o un marcador similar.

Disponibilidad

pwd está disponible en Unix, pero no en WASI ni iOS. Windows utiliza otro modelo de cuentas.

try:
    import pwd
except ImportError:
    pwd = None

Para software multiplataforma, usa abstracciones de mayor nivel cuando solo necesites el usuario actual o el directorio home.

Campos de una cuenta

Las funciones devuelven un objeto similar a una tupla con estos atributos:

pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell

pw_uid y pw_gid son enteros. Los demás valores son strings.

Consultar por UID

import os
import pwd

cuenta = pwd.getpwuid(os.getuid())
print(cuenta.pw_name)
print(cuenta.pw_dir)
print(cuenta.pw_shell)

getpwuid() genera KeyError cuando no existe una entrada visible para ese UID.

Consultar por nombre

import pwd

try:
    cuenta = pwd.getpwnam("deploy")
except KeyError:
    print("Usuario inexistente")
else:
    print(cuenta.pw_uid, cuenta.pw_gid)

En una API pública, convierte el KeyError en un resultado de dominio claro en lugar de exponer una excepción interna.

UID real y efectivo

os.getuid() devuelve el UID real y os.geteuid() el UID efectivo. Pueden ser diferentes en programas setuid, containers o procesos que cambian privilegios.

real = pwd.getpwuid(os.getuid())
efectiva = pwd.getpwuid(os.geteuid())

Para permisos, entiende qué identidad utiliza el kernel en cada operación.

No confíes en variables de entorno

USER, LOGNAME y HOME pueden faltar o ser manipuladas.

cuenta = pwd.getpwuid(os.geteuid())
home = cuenta.pw_dir

Con sudo, el usuario efectivo puede ser root y el usuario original aparecer en SUDO_UID. Esa diferencia debe formar parte de una política explícita.

Directorio home

pw_dir contiene el home registrado por el proveedor de identidad. No garantiza que el directorio exista, esté montado o sea accesible.

from pathlib import Path

home = Path(cuenta.pw_dir)
if home.is_dir():
    print(home)

No crees archivos en el home de otra cuenta sin verificar ownership, permisos y finalidad.

Shell configurado

pw_shell puede contener /bin/bash, /bin/zsh, /usr/sbin/nologin, /bin/false u otro programa.

Ese campo no demuestra que la cuenta pueda autenticarse ni autoriza ejecutar el shell. Las cuentas de servicio pueden usar valores especiales o vacíos.

Campo GECOS

pw_gecos suele almacenar nombre completo o comentarios administrativos, pero su formato no es un contrato estable. Puede contener comas y datos personales.

No lo uses como identificador único y limita su exposición por privacidad.

pw_passwd no sirve para autenticar

En sistemas con shadow passwords, pw_passwd suele contener x o *. Aunque aparezca un hash, compararlo manualmente no es una arquitectura segura.

Usa PAM, el servicio corporativo de identidad, OAuth, SSH o el mecanismo soportado por el sistema. Nunca solicites una contraseña para validarla con pwd.

Listar todas las cuentas

import pwd

for cuenta in pwd.getpwall():
    print(cuenta.pw_uid, cuenta.pw_name, cuenta.pw_shell)

El orden es arbitrario. En máquinas conectadas a LDAP, SSSD, NIS u otros proveedores NSS, la operación puede ser lenta y devolver muchas entradas.

NSS y fuentes remotas

Las funciones siguen la configuración Name Service Switch del sistema. La información puede provenir de /etc/passwd, LDAP, SSSD, NIS, archivos de container o plugins.

Una consulta aparentemente local puede utilizar red y bloquear. No la ejecutes repetidamente en un hot path sin una estrategia de cache y control de latencia.

Cache

Para consultas frecuentes, un cache pequeño puede reducir trabajo.

from functools import lru_cache
import pwd

@lru_cache(maxsize=256)
def usuario_por_uid(uid):
    return pwd.getpwuid(uid)

lru_cache no expira. En servicios largos, cambios de cuenta pueden quedar ocultos. Usa TTL cuando la actualización sea importante.

Mostrar ownership de archivos

pwd permite convertir el UID de un archivo en un nombre.

import os
import pwd

info = os.stat("archivo.txt")
try:
    propietario = pwd.getpwuid(info.st_uid).pw_name
except KeyError:
    propietario = str(info.st_uid)

Conserva el UID numérico como fallback. Un archivo puede pertenecer a una cuenta eliminada o a otro namespace.

Containers y namespaces

Dentro de un container, el proceso puede ejecutar con un UID sin entrada en /etc/passwd. Es común en imágenes minimalistas y plataformas que asignan UIDs aleatorios.

No conviertas esa ausencia en error fatal cuando el número sea suficiente para logs u ownership.

UID cero

UID 0 suele representar root, pero no compruebes privilegios comparando el nombre root.

if os.geteuid() == 0:
    print("El UID efectivo es cero")

Incluso UID cero puede estar limitado por namespaces, capabilities, SELinux, AppArmor o el runtime del container.

Reducir privilegios

Un servicio iniciado como root puede resolver una cuenta y después reducir privilegios.

import os
import pwd

cuenta = pwd.getpwnam("appuser")
os.initgroups(cuenta.pw_name, cuenta.pw_gid)
os.setgid(cuenta.pw_gid)
os.setuid(cuenta.pw_uid)

La secuencia es sensible: prepara archivos, directorios y descriptors antes; no intentes recuperar privilegio. Siempre que sea posible, deja que systemd, Docker o el supervisor inicie el proceso con el usuario correcto.

Grupos suplementarios

pw_gid informa solo el grupo primario. Para membresías adicionales, usa grp, os.getgroups() u os.getgrouplist().

El siguiente conjunto de este lote cubrirá el módulo grp.

Expansión de virgulilla

os.path.expanduser("~nombre") puede consultar la misma base. Cuando necesites tratamiento explícito de errores, usa pwd.getpwnam(nombre).pw_dir.

Validación de nombres

No construyas rutas concatenando un login no confiable. Resuelve la cuenta, utiliza el home registrado y comprueba que el resultado permanezca dentro de una raíz permitida.

Los caracteres válidos en nombres cambian según la plataforma y el proveedor de identidad.

Privacidad

getpwall() puede revelar nombres de cuentas, homes y shells. No expongas la base completa en una API web o en logs sin necesidad y autorización.

Latencia y concurrencia

La implementación NSS puede leer archivos de configuración o consultar servicios remotos. No asumas latencia constante porque la API sea síncrona y pequeña.

Manejo de errores

KeyError indica que no se encontró la entrada. Fallos de proveedor o del sistema pueden aparecer de otra forma. Cuando importe, diferencia cuenta ausente de servicio de identidad indisponible.

Integración con logs

Al registrar una identidad en syslog en Python, utiliza UID numérico y un nombre sanitizado, sin exponer campos GECOS o homes completos salvo que sean necesarios.

Procesos limitados

Una cuenta sin privilegios complementa los límites descritos en resource en Python. Ninguna de las dos medidas sustituye una sandbox completa.

Pruebas

Prueba cuentas existentes y ausentes, UIDs sin nombre, container con UID aleatorio, LDAP lento, home inexistente, shell nologin, cuenta eliminada, root dentro de namespace, cache desactualizado y plataformas sin el módulo.

Los tests unitarios no deberían depender de cuentas reales del host. Encapsula las consultas y usa objetos fake.

Errores comunes

Los fallos frecuentes son usar pw_passwd para autenticar, confiar en $USER, tratar pw_gid como todos los grupos, asumir que el home existe, listar cuentas en cada request, fallar cuando un UID no tiene nombre y exponer la base sin necesidad.

Conclusión

pwd es la interfaz estándar para resolver identidades Unix por UID o login. Úsalo para nombres, homes, shells y ownership, conservando IDs numéricos y considerando NSS, containers, latencia y privacidad.

No lo uses para validar contraseñas ni confundas existencia de cuenta con autorización. Consulta la documentación oficial de pwd y el manual passwd(5).

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Close-up of stacked logs showing natural textures and patterns, suitable for firewood or decor.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    syslog en Python: envía logs a Unix

    Aprende syslog en Python para enviar logs Unix con prioridades, facilities, máscaras, contenido estructurado y protección contra log injection.

    Ler mais

    Tempo de leitura: 4 minutos
    26/08/2026
    A CPU and RAM sticks displayed on a white surface, showcasing computer hardware components.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    resource en Python: límites de CPU y memoria

    Aprende resource en Python para medir CPU, pico de memoria y page faults, y limitar archivos, procesos, descriptors y address

    Ler mais

    Tempo de leitura: 5 minutos
    26/08/2026
    Close-up of a person using a metro card machine for public transport payment indoors.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    pty en Python: automatiza terminales Unix

    Aprende pty en Python para ejecutar y probar programas interactivos, controlar pseudo-terminales, EOF, resize, señales y timeouts.

    Ler mais

    Tempo de leitura: 5 minutos
    25/08/2026
    Detailed view of programming code in a dark theme on a computer screen.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    tty en Python: modos raw y cbreak

    Aprende tty en Python para modos raw y cbreak, lectura de teclas, secuencias, Unicode y restauración segura del terminal Unix.

    Ler mais

    Tempo de leitura: 5 minutos
    25/08/2026
    Laptop displaying code with reflection, perfect for tech and programming themes.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    termios en Python: control seguro del terminal

    Aprende termios en Python para modo canónico, echo, lectura de teclas, baud rate, colas, ventana y restauración segura del TTY.

    Ler mais

    Tempo de leitura: 5 minutos
    25/08/2026
    Multiple padlocks securing a green chain link fence, symbolizing safety and protection.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    fcntl en Python: locks y control de archivos

    Aprende fcntl en Python para locks, flags de descriptors, ioctl, pipes y control Unix, evitando buffers inválidos y corrupción de

    Ler mais

    Tempo de leitura: 5 minutos
    25/08/2026