¿Hay alguna forma portátil de obtener el nombre de usuario actual en Python?

598

¿Hay alguna forma portátil de obtener el nombre de usuario del usuario actual en Python (es decir, una que funcione tanto en Linux como en Windows, al menos)? Funcionaría como os.getuid:

>>> os.getuid()
42
>>> os.getusername()
'slartibartfast'

Busqué en Google y me sorprendió no encontrar una respuesta definitiva (aunque quizás solo estaba buscando en Google mal). El módulo pwd proporciona una forma relativamente fácil de lograr esto en, por ejemplo, Linux, pero no está presente en Windows. Algunos de los resultados de búsqueda sugirieron que obtener el nombre de usuario en Windows puede ser complicado en ciertas circunstancias (por ejemplo, ejecutarse como un servicio de Windows), aunque no lo he verificado.

Jacob Gabrielson
fuente
¡No funciona en mi caja de Linux!
Riccardo
55
import pwd, os; print pwd.getpwuid(os.getuid()).pw_gecosoimport pwd, os; print pwd.getpwuid(os.getuid()).pw_name
chown
getusername () no es un método válido en el módulo OS
Matt Bruzek
17
@MattBruzek Ese fue el punto de OP allí. Estaba imaginando cómo se podría llamar a tal función si existiera.
meter

Respuestas:

836

Mira el módulo getpass

import getpass
getpass.getuser()
'kostya'

Disponibilidad: Unix, Windows


ps Por comentario a continuación " esta función analiza los valores de varias variables de entorno para determinar el nombre de usuario. Por lo tanto, no se debe confiar en esta función para fines de control de acceso (o posiblemente para cualquier otro propósito, ya que permite a cualquier usuario suplantar a cualquier otro ) " .

Konstantin Tenzin
fuente
100
Parece que esta función analiza los valores de varias variables de entorno para determinar el nombre de usuario. Por lo tanto, no se debe confiar en esta función para fines de control de acceso (o posiblemente para cualquier otro propósito, ya que permite que cualquier usuario se haga pasar por otro).
Greg Hewgill
25
No hay nada malo con getpass.getuser (), ya que no pretende autenticar al usuario. El propósito de la función es determinar quién dice ser el usuario sin preguntarle directamente al usuario.
Walker Hale IV
77
Eso no funciona si has hecho un su. $ echo $ USER hithwen $ su julia Contraseña: $ echo $ USER julia $ python >>> import getpass >>> getpass.getuser () 'hithwen'
hithwen
66
@GregHewgill plantea un muy buen punto, pero de hecho, descubrir el nombre de usuario de una manera simple no autenticada como esta tiene algunas aplicaciones. Mi caso de uso actual: etiquetar algunos recursos de prueba compartidos con un nombre de usuario para una fácil limpieza posterior. (Por lo tanto, es más fácil averiguar de quién es el desastre.)
driftcatcher
16
Y estoy de acuerdo con @GregHewgill para fines de control de acceso, pero estoy totalmente en desacuerdo con 'cualquier otro propósito', es como decir "No uses $ USER en un script de shell". Gran punto sobre el control de acceso, pero hay muchos otros usos que no implican autenticación.
nevelis
119

Su mejor apuesta sería combinar os.getuid()con pwd.getpwuid():

import os
import pwd

def get_username():
    return pwd.getpwuid( os.getuid() )[ 0 ]

Consulte los documentos de pwd para obtener más detalles:

http://docs.python.org/library/pwd.html

Liam Chasteen
fuente
51
Alternativamente (ligeramente más agradable para leer): pwd.getpwuid(os.getuid()).pw_name.
Brian M. Hunt
66
¿Qué hace en Windows? Quizás uno podría intentar esto, y si falla, recurrir a los métodos 'getpass / env var'.
Jonathan Hartley
2
Esta es la forma correcta si necesita obtener el nombre de usuario con y sin iniciar sesión.
Derrick Zhang
55
@ JonathanHartley:ImportError: No module named pwd
Justin
1
Este método está en sistemas tipo Unix muy superiores a la respuesta de Konstantin Tenzin, porque maneja el sudocaso correctamente. (Soy consciente de que el OP no solicitó sistemas similares a Unix.)
Halloleo
86

También puedes usar:

 os.getlogin()
Marcin Augustyniak
fuente
29
En Linux, getlogin () devuelve el nombre del "usuario conectado en la terminal de control del proceso". Por lo tanto, falla cuando no hay un terminal de control, por ejemplo, en una aplicación mod_python.
Vebjorn Ljosa
23
No disponible para Windows
Walker Hale IV
3
Si usó su, entonces esto no devolverá al usuario actual, sino al usuario que inició sesión originalmente.
Trevor Allred
44
funciona en Windows ... Python 3.4.1 (v3.4.1: c0e311e010fc, 18 de mayo de 2014, 10:38:22) [MSC v.1600 32 bit (Intel)] en win32 Escriba "help", "copyright", "créditos" o "licencia" para más información. >>> importar os; os.getlogin () 'jrb'
Naib
55
Solo está disponible en Windows para Python 3.x.
Zitrax
71

Probablemente puedas usar:

os.environ.get('USERNAME')

o

os.environ.get('USER')

Pero no será seguro porque las variables de entorno se pueden cambiar.

Nadia Alramli
fuente
18
os.getenv(...)está en desuso a favor de os.environ[...].
Mike Graham
11
¿No debería ser USER en lugar de USERNAME?
Karl Bartel
77
@MikeGraham os.getenvno parece estar en desuso ...?
dbr
44
Sí, exactamente USER vs USERNAME es exactamente lo que no es portátil, por lo que no proporciona la respuesta correcta.
Peter M
2
USERNAME es para Windows, USER es para Linux
Sabrina
22

Estos podrían funcionar. No sé cómo se comportan cuando se ejecutan como un servicio. Ellos no son portátiles, pero eso es lo que os.namey ifdeclaraciones son para.

win32api.GetUserName()

win32api.GetUserNameEx(...) 

Ver: http://timgolden.me.uk/python/win32_how_do_i/get-the-owner-of-a-file.html

Adán
fuente
30
Esta respuesta es al menos tan útil como la (inútil) respuesta de 25 votos votados solo para Unix.
Tom B
3
> "Al menos tan útil" De acuerdo. Presumiblemente, la respuesta correcta es una combinación de los dos.
Jonathan Hartley
Si está atascado en Python 2 en Windows, esta es la única forma segura de hacerlo. Todas las otras formas se pueden engañar ejecutando SET USERNAME=FAKEantes de su comando de Python
CodeKid
21

Si necesita esto para obtener el directorio de inicio del usuario, a continuación podría considerarse portátil (win32 y linux al menos), parte de una biblioteca estándar.

>>> os.path.expanduser('~')
'C:\\Documents and Settings\\johnsmith'

También podría analizar dicha cadena para obtener solo el último componente de ruta (es decir, nombre de usuario).

Ver: os.path.expanduser

HezniK
fuente
99
El directorio personal de alguien no siempre refleja su nombre de usuario.
dreamlax
Esto funciona tanto en Linux como en Windows
Sabrina
Desafortunadamente, si configura la variable HOME en Windows, esto le devolverá ese valor.
GLRoman
15

Para mí, usar el osmódulo se ve mejor para la portabilidad: funciona mejor tanto en Linux como en Windows.

import os

# Gives user's home directory
userhome = os.path.expanduser('~')          

print "User's home Dir: " + userhome

# Gives username by splitting path based on OS
print "username: " + os.path.split(userhome)[-1]           

Salida:

Ventanas:

Dir de inicio del usuario: C: \ Users \ myuser

nombre de usuario: myuser

Linux:

Dir de inicio del usuario: / root

nombre de usuario: root

No es necesario instalar ningún módulo o extensión.


fuente
16
Esta solución es inteligente, pero hace algunas suposiciones que no siempre son ciertas. No hay ninguna restricción que requiera que el nombre de usuario aparezca en la ruta homedir en Linux. Sucede que es el caso la mayor parte del tiempo, pero un administrador de sistemas puede configurar el homedir de un usuario para lo que quieran.
Joe Holloway
Establecer la variable HOME derrota esto.
GLRoman
11

Combinado pwdy getpassenfoque, basado en otras respuestas:

try:
  import pwd
except ImportError:
  import getpass
  pwd = None

def current_user():
  if pwd:
    return pwd.getpwuid(os.geteuid()).pw_name
  else:
    return getpass.getuser()
anatoly techtonik
fuente
9

Para UNIX, al menos, esto funciona ...

import commands
username = commands.getoutput("echo $(whoami)")
print username

editar: acabo de buscarlo y esto funciona en Windows y UNIX:

import commands
username = commands.getoutput("whoami")

En UNIX, devuelve su nombre de usuario, pero en Windows, devuelve el grupo de su usuario, barra oblicua, su nombre de usuario.

-

ES DECIR

UNIX devuelve: "nombre de usuario"

Windows devuelve: "dominio / nombre de usuario"

-

Es interesante, pero probablemente no sea ideal a menos que esté haciendo algo en el terminal de todos modos ... en cuyo caso probablemente estaría usando os.systempara empezar. Por ejemplo, hace un tiempo necesitaba agregar mi usuario a un grupo, así que lo hice (esto está en Linux, eso sí)

import os
os.system("sudo usermod -aG \"group_name\" $(whoami)")
print "You have been added to \"group_name\"! Please log out for this to take effect"

Siento que es más fácil de leer y no tienes que importar pwd o getpass.

También siento que tener "dominio / usuario" podría ser útil en ciertas aplicaciones en Windows.

dylnmc
fuente
1
Windows domain/user no regresagroup/user
RealHowTo
44
El módulo de comandos no funciona en Windows. Es un módulo específico de UNIX (ver docs.python.org/2/library/commands.html ). Ahora está en desuso y se recomienda el subproceso en su lugar. user = subprocess.check_output("whoami").replace("\r\n", "")
ConnectedSystems
k; luego use el subproceso ...
jeez
2 comentarios. command.whoami fue excelente, incluso en el contexto de un servicio que se ejecuta con un nombre de usuario diferente. es decir, chpst -u nobody python ./manage.py celerycam --pidfile=/var/run/celerycam/celerycam.pid no tengo a nadie . segundo, user = subprocess.check_output("whoami").strip() es más portátil que los reemplazos de alimentación de línea anteriores. commandsvs subprocessparece quisquilloso pero faltan comandos en python 3.
JL Peyret
5

Escribí el módulo plx hace algún tiempo para obtener el nombre de usuario de forma portátil en Unix y Windows (entre otras cosas): http://www.decalage.info/en/python/plx

Uso:

import plx

username = plx.get_username()

(requiere extensiones win32 en Windows)

decalaje
fuente
4

Usando solo libs de python estándar:

from os import environ,getcwd
getUser = lambda: environ["USERNAME"] if "C:" in getcwd() else environ["USER"]
user = getUser()

Funciona en Windows, Mac o Linux

Alternativamente, puede eliminar una línea con una invocación inmediata:

from os import environ,getcwd
user = (lambda: environ["USERNAME"] if "C:" in getcwd() else environ["USER"])()
ThisGuyCantEven
fuente
1
getpass también es una lib estándar
jodag
no funciona para mí en win10, python3.7.4. Supongo que se queja de que "USUARIO" no se encuentra en las variables de entorno. Supongo que getpass es una mejor opción de todos modos.
Rika
3

Puede obtener el nombre de usuario actual en Windows yendo a través de la API de Windows, aunque es un poco engorroso invocarlo a través de los ctypes FFI ( GetCurrentProcessOpenProcessTokenGetTokenInformationLookupAccountSid ).

Escribí un pequeño módulo que puede hacer esto directamente desde Python, getuser.py . Uso:

import getuser
print(getuser.lookup_username())

Funciona tanto en Windows como en * nix (este último utiliza el pwd módulo como se describe en las otras respuestas).

Michael Kropat
fuente