Existe-t-il un moyen portable d'obtenir le nom d'utilisateur actuel en Python?

598

Existe-t-il un moyen portable d'obtenir le nom d'utilisateur de l'utilisateur actuel en Python (c'est-à-dire, qui fonctionne sous Linux et Windows, au moins). Cela fonctionnerait comme os.getuid:

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

J'ai fait des recherches sur Google et j'ai été surpris de ne pas trouver de réponse définitive (même si je cherchais peut-être mal sur Google). Le module pwd fournit un moyen relativement facile d'y parvenir sous, disons, Linux, mais il n'est pas présent sur Windows. Certains résultats de recherche suggèrent que l'obtention du nom d'utilisateur sous Windows peut être compliquée dans certaines circonstances (par exemple, en tant que service Windows), bien que je ne l'ai pas vérifié.

Jacob Gabrielson
la source
Ça ne marche pas sur ma box Linux!
Riccardo
5
import pwd, os; print pwd.getpwuid(os.getuid()).pw_gecosouimport pwd, os; print pwd.getpwuid(os.getuid()).pw_name
chown
getusername () n'est pas une méthode valide dans le module os Python: docs.python.org/2.7/library/os.html
Matt Bruzek
17
@MattBruzek C'était là le point d'OP. Il imaginait comment une telle fonction pourrait être appelée si elle existait.
poke

Réponses:

836

Regardez le module getpass

import getpass
getpass.getuser()
'kostya'

Disponibilité: Unix, Windows


ps Par commentaire ci-dessous ", cette fonction examine les valeurs de diverses variables d'environnement pour déterminer le nom d'utilisateur. Par conséquent, cette fonction ne doit pas être utilisée à des fins de contrôle d'accès (ou éventuellement à toute autre fin, car elle permet à tout utilisateur de se faire passer pour n'importe quel autre ). "

Konstantin Tenzin
la source
100
Il semble que cette fonction examine les valeurs de diverses variables d'environnement pour déterminer le nom d'utilisateur. Par conséquent, cette fonction ne doit pas être utilisée à des fins de contrôle d'accès (ou éventuellement à toute autre fin, car elle permet à tout utilisateur de se faire passer pour n'importe quel autre).
Greg Hewgill
25
Il n'y a rien de mal avec getpass.getuser (), car ne prétend pas authentifier l'utilisateur. Le but de la fonction est de déterminer qui prétend être l’utilisateur sans lui demander directement.
Walker Hale IV
7
Cela ne fonctionne pas si vous avez fait un su. $ echo $ USER hithwen $ su julia Mot de passe: $ echo $ USER julia $ python >>> import getpass >>> getpass.getuser () 'hithwen'
hithwen
6
@GregHewgill soulève un très bon point, mais en effet, trouver le nom d'utilisateur d'une manière simple et non authentifiée comme celle-ci a certaines applications. Mon cas d'utilisation actuel: baliser certaines ressources de test partagées avec un nom d'utilisateur pour un nettoyage facile plus tard. (Il est donc plus facile de déterminer à qui appartient le gâchis.)
driftcatcher
16
Et je suis d'accord avec @GregHewgill à des fins de contrôle d'accès, mais je suis complètement en désaccord avec «tout autre objectif» - c'est comme dire «N'utilisez pas $ USER dans un script shell». Excellent point sur le contrôle d'accès, mais il existe de nombreuses autres utilisations qui n'impliquent pas l'authentification.
nevelis
119

Le mieux serait de combiner os.getuid()avec pwd.getpwuid():

import os
import pwd

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

Reportez-vous à la documentation de pwd pour plus de détails:

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

Liam Chasteen
la source
51
Vous pouvez également ( un peu plus agréable à lire): pwd.getpwuid(os.getuid()).pw_name.
Brian M. Hunt
6
Que fait-il sous Windows? Peut-être que l'on pourrait essayer cela, et si cela échoue, se replier sur les méthodes de merde 'getpass / env var'.
Jonathan Hartley
2
C'est la bonne façon si vous avez besoin d'obtenir le nom d'utilisateur avec et sans vous connecter.
Derrick Zhang
5
@JonathanHartley:ImportError: No module named pwd
Justin
1
Cette méthode est sur des systèmes de type Unix bien supérieure à la réponse de Konstantin Tenzin, car elle gère sudocorrectement le cas. (Je sais que l'OP n'a pas demandé de systèmes de type Unix.)
halloleo
86

Vous pouvez aussi utiliser:

 os.getlogin()
Marcin Augustyniak
la source
29
Sous linux, getlogin () renvoie le nom de "l'utilisateur connecté sur le terminal de contrôle du processus". Il échoue donc lorsqu'il n'y a pas de terminal de contrôle, par exemple dans une application mod_python.
Vebjorn Ljosa
23
Non disponible pour Windows
Walker Hale IV
3
Si vous avez utilisé su, cela ne renverra pas l'utilisateur actuel, mais l'utilisateur connecté à l'origine.
Trevor Allred du
4
fonctionne sur Windows ... Python 3.4.1 (v3.4.1: c0e311e010fc, 18 mai 2014, 10:38:22) [MSC v.1600 32 bits (Intel)] sur win32 Tapez "help", "copyright", "crédits" ou "licence" pour plus d'informations. >>> importation os; os.getlogin () 'jrb'
Naib
5
Il n'est disponible que sur Windows pour Python 3.x.
Zitrax
71

Vous pouvez probablement utiliser:

os.environ.get('USERNAME')

ou

os.environ.get('USER')

Mais cela ne sera pas sûr car les variables d'environnement peuvent être modifiées.

Nadia Alramli
la source
18
os.getenv(...)est déconseillé en faveur de os.environ[...].
Mike Graham
11
Ne devrait-il pas être USER au lieu de USERNAME?
Karl Bartel
7
@MikeGraham os.getenvne semble pas être obsolète ..?
dbr
4
Oui, exactement USER vs USERNAME est exactement ce qui n'est pas portable, donc il ne fournit pas la bonne réponse.
Peter M
2
USERNAME est pour Windows, USER est pour Linux
Sabrina
22

Cela pourrait fonctionner. Je ne sais pas comment ils se comportent lors de l'exécution en tant que service. Ils ne sont pas portables, mais c'est ce que os.nameet les ifdéclarations sont pour.

win32api.GetUserName()

win32api.GetUserNameEx(...) 

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

Adam
la source
30
Cette réponse est au moins aussi utile que la réponse (inutile) de 25 votes unix uniquement (unix).
Tom B
3
> "Au moins aussi utile" D'accord. Vraisemblablement, la bonne réponse est une combinaison des deux.
Jonathan Hartley
Si vous êtes bloqué sur python 2 sous Windows, c'est le seul moyen sûr de le faire. Toutes les autres façons peuvent être trompées en exécutant SET USERNAME=FAKEavant votre commande python
CodeKid
21

Si vous en avez besoin pour obtenir le répertoire personnel de l'utilisateur, ci-dessous peut être considéré comme portable (win32 et linux au moins), faisant partie d'une bibliothèque standard.

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

Vous pouvez également analyser une telle chaîne pour obtenir uniquement le dernier composant du chemin (c'est-à-dire le nom d'utilisateur).

Voir: os.path.expanduser

HezniK
la source
9
Le répertoire personnel de quelqu'un ne reflète pas toujours son nom d'utilisateur.
dreamlax
Cela fonctionne sur Linux et Windows
Sabrina
Malheureusement, si vous définissez la variable HOME dans Windows, cela lui retournera cette valeur.
GLRoman
15

Pour moi, l'utilisation du osmodule est la meilleure pour la portabilité: fonctionne mieux sous Linux et 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]           

Production:

Les fenêtres:

Accueil de l'utilisateur Dir: C: \ Users \ myuser

nom d'utilisateur: myuser

Linux:

Accueil de l'utilisateur Dir: / root

nom d'utilisateur: root

Pas besoin d'installer de modules ou d'extensions.


la source
16
Cette solution est intelligente, mais émet certaines hypothèses qui ne sont pas toujours vraies. Il n'y a aucune contrainte qui oblige le nom d'utilisateur à apparaître dans le chemin homedir sous Linux. Il se trouve que c'est le cas la plupart du temps, mais un administrateur système peut définir le homedir d'un utilisateur sur ce qu'il veut.
Joe Holloway
La définition de la variable HOME échoue.
GLRoman
11

Combiné pwdet getpassapproche, basé sur d'autres réponses:

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
la source
9

Pour UNIX, au moins, cela fonctionne ...

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

edit: Je viens de le chercher et cela fonctionne sur Windows et UNIX:

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

Sous UNIX, il renvoie votre nom d'utilisateur, mais sous Windows, il renvoie votre groupe d'utilisateurs, slash, votre nom d'utilisateur.

-

C'EST À DIRE

UNIX renvoie: "nom d'utilisateur"

Windows renvoie: "domaine / nom d'utilisateur"

-

C'est intéressant, mais probablement pas idéal à moins que vous ne fassiez quelque chose dans le terminal de toute façon ... auquel cas vous utiliseriez probablement os.systempour commencer. Par exemple, il y a quelque temps, j'avais besoin d'ajouter mon utilisateur à un groupe, alors je l'ai fait (c'est sous Linux, remarquez)

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"

Je pense que c'est plus facile à lire et que vous n'avez pas besoin d'importer pwd ou getpass.

Je pense également que le fait d'avoir "domaine / utilisateur" pourrait être utile dans certaines applications de Windows.

dylnmc
la source
1
domain/usergroup/user
WIndows
4
Le module de commandes ne fonctionne pas sous Windows. Il s'agit d'un module spécifique à UNIX (voir docs.python.org/2/library/commands.html ). Il est désormais obsolète et un sous-processus est recommandé à la place. user = subprocess.check_output("whoami").replace("\r\n", "")
ConnectedSystems
k; puis utilisez le sous-processus ... jeez
dylnmc
2 remarques. commands.whoami a très bien fonctionné, même dans le contexte d'un service exécuté sous un nom d'utilisateur différent. c'est à dire avec chpst -u nobody python ./manage.py celerycam --pidfile=/var/run/celerycam/celerycam.pid je n'ai personne . deuxièmement, user = subprocess.check_output("whoami").strip() est plus portable que les sauts de ligne de remplacement ci-dessus. commandsvs subprocesssemble nitpicky mais les commandes sont absentes de python 3.
JL Peyret
5

J'ai écrit le module plx il y a quelque temps pour obtenir le nom d'utilisateur de manière portable sur Unix et Windows (entre autres): http://www.decalage.info/en/python/plx

Usage:

import plx

username = plx.get_username()

(il nécessite des extensions win32 sous Windows)

décalcomanie
la source
4

Utiliser uniquement des bibliothèques python standard:

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

Fonctionne sur Windows, Mac ou Linux

Alternativement, vous pouvez supprimer une ligne avec un appel immédiat:

from os import environ,getcwd
user = (lambda: environ["USERNAME"] if "C:" in getcwd() else environ["USER"])()
ThisGuyCantEven
la source
1
getpass est également une bibliothèque standard
jodag
ne fonctionne pas pour moi dans win10, python3.7.4. son se plaindre de «USER» ne se trouve pas dans les variables d'environnement je suppose. Je suppose que getpass est de toute façon un meilleur choix.
Rika
3

Vous pouvez obtenir le nom d'utilisateur actuel sous Windows en passant par l'API Windows, bien qu'il soit un peu lourd à appeler via les ctypes FFI ( GetCurrentProcessOpenProcessTokenGetTokenInformation LookupAccountSid ).

J'ai écrit un petit module qui peut le faire directement depuis Python, getuser.py . Usage:

import getuser
print(getuser.lookup_username())

Il fonctionne à la fois sur Windows et * nix (ce dernier utilise le pwdmodule comme décrit dans les autres réponses).

Michael Kropat
la source