Gibt es eine tragbare Möglichkeit, den aktuellen Benutzernamen in Python abzurufen?

597

Gibt es eine tragbare Möglichkeit, den Benutzernamen des aktuellen Benutzers in Python abzurufen (dh eine, die zumindest unter Linux und Windows funktioniert)? Es würde funktionieren wie os.getuid:

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

Ich googelte herum und war überrascht, keine endgültige Antwort zu finden (obwohl ich vielleicht nur schlecht googelte). Das pwd- Modul bietet eine relativ einfache Möglichkeit, dies beispielsweise unter Linux zu erreichen, ist jedoch unter Windows nicht vorhanden. Einige der Suchergebnisse deuteten darauf hin, dass das Abrufen des Benutzernamens unter Windows unter bestimmten Umständen kompliziert sein kann (z. B. als Windows-Dienst ausgeführt), obwohl ich dies nicht überprüft habe.

Jacob Gabrielson
quelle
Es funktioniert nicht auf meiner Linux-Box!
Riccardo
5
import pwd, os; print pwd.getpwuid(os.getuid()).pw_gecosoderimport pwd, os; print pwd.getpwuid(os.getuid()).pw_name
chown
getusername () ist keine gültige Methode im OS
Matt Bruzek
17
@ MattBruzek Das war der Punkt von OP dort. Er stellte sich vor, wie eine solche Funktion aufgerufen werden könnte, wenn sie existierte.
Poke

Antworten:

836

Schauen Sie sich das Getpass- Modul an

import getpass
getpass.getuser()
'kostya'

Verfügbarkeit: Unix, Windows


ps Pro Kommentar unten " Diese Funktion untersucht die Werte verschiedener Umgebungsvariablen, um den Benutzernamen zu bestimmen. Daher sollte diese Funktion nicht für Zugriffskontrollzwecke (oder möglicherweise für andere Zwecke) verwendet werden, da sie es jedem Benutzer ermöglicht, sich als ein anderer auszugeben ). "

Konstantin Tenzin
quelle
100
Es scheint, dass diese Funktion die Werte verschiedener Umgebungsvariablen untersucht, um den Benutzernamen zu bestimmen. Daher sollte diese Funktion nicht für Zugriffskontrollzwecke (oder möglicherweise für andere Zwecke) verwendet werden, da sie es jedem Benutzer ermöglicht, sich als andere auszugeben.
Greg Hewgill
25
An getpass.getuser () ist nichts auszusetzen, da nicht behauptet wird, den Benutzer zu authentifizieren. Der Zweck der Funktion besteht darin, zu bestimmen, wer der Benutzer zu sein behauptet, ohne den Benutzer direkt zu fragen.
Walker Hale IV
7
Das funktioniert nicht, wenn Sie eine su gemacht haben. $ echo $ USER hithwen $ su julia Passwort: $ echo $ USER julia $ python >>> getpass importieren >>> getpass.getuser () 'hithwen'
hithwen
6
@GregHewgill spricht einen sehr guten Punkt an, aber tatsächlich hat das Herausfinden des Benutzernamens auf eine einfache, nicht authentifizierte Weise wie diese einige Anwendungen. Mein aktueller Anwendungsfall: Kennzeichnen einiger freigegebener Testressourcen mit einem Benutzernamen für eine spätere einfache Bereinigung. (So ​​ist es einfacher herauszufinden, wessen Chaos wessen ist.)
Driftcatcher
16
Und ich stimme @GregHewgill für die Zugriffskontrolle zu, bin aber mit "jedem anderen Zweck" völlig nicht einverstanden - das ist so, als würde man sagen "Verwenden Sie $ USER nicht in einem Shell-Skript". Ein großartiger Punkt zur Zugriffskontrolle, aber es gibt viele andere Verwendungszwecke, bei denen keine Authentifizierung erforderlich ist.
Nevelis
119

Am besten kombinieren Sie os.getuid()mit pwd.getpwuid():

import os
import pwd

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

Weitere Informationen finden Sie in den pwd-Dokumenten:

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

Liam Chasteen
quelle
51
Alternativ (etwas schöner zu lesen) : pwd.getpwuid(os.getuid()).pw_name.
Brian M. Hunt
6
Was macht es unter Windows? Vielleicht könnte man dies versuchen, und wenn es fehlschlägt, auf die beschissenen 'getpass / env var'-Methoden zurückgreifen.
Jonathan Hartley
2
Dies ist der richtige Weg, wenn Sie den Benutzernamen mit und ohne Anmeldung erhalten müssen.
Derrick Zhang
5
@ JonathanHartley:ImportError: No module named pwd
Justin
1
Diese Methode ist auf Unix-ähnlichen Systemen der Antwort von Konstantin Tenzin weit überlegen, da sie den sudoFall korrekt behandelt. (Ich bin mir bewusst, dass das OP nicht nach Unix-ähnlichen Systemen gefragt hat.)
Halloleo
86

Sie können auch verwenden:

 os.getlogin()
Marcin Augustyniak
quelle
29
Unter Linux gibt getlogin () den Namen des "am steuernden Terminal des Prozesses angemeldeten Benutzers" zurück. Es schlägt daher fehl, wenn kein steuerndes Terminal vorhanden ist, z. B. in einer mod_python-Anwendung.
Vebjorn Ljosa
23
Nicht verfügbar für Windows
Walker Hale IV
3
Wenn Sie su verwendet haben, wird dadurch nicht der aktuelle Benutzer, sondern der ursprünglich angemeldete Benutzer zurückgegeben.
Trevor Allred
4
funktioniert unter Windows ... Python 3.4.1 (v3.4.1: c0e311e010fc, 18. Mai 2014, 10:38:22) [MSC v.1600 32 Bit (Intel)] unter win32 Geben Sie "help", "copyright", "Credits" oder "Lizenz" für weitere Informationen. >>> os importieren; os.getlogin () 'jrb'
Naib
5
Es ist nur unter Windows für Python 3.x verfügbar.
Zitrax
71

Sie können wahrscheinlich verwenden:

os.environ.get('USERNAME')

oder

os.environ.get('USER')

Dies ist jedoch nicht sicher, da Umgebungsvariablen geändert werden können.

Nadia Alramli
quelle
18
os.getenv(...)wird zugunsten von abgelehnt os.environ[...].
Mike Graham
11
Sollte es nicht USER statt USERNAME sein?
Karl Bartel
7
@ MikeGraham os.getenvscheint nicht veraltet zu sein ..?
dbr
4
Ja, genau USER vs USERNAME ist genau das, was nicht portabel ist, daher liefert es nicht die richtige Antwort.
Peter M
2
USERNAME ist für Windows, USER ist für Linux
Sabrina
22

Diese könnten funktionieren. Ich weiß nicht, wie sie sich verhalten, wenn sie als Dienst ausgeführt werden. Sie sind nicht tragbar, aber das ist , was os.nameund ifAussagen sind.

win32api.GetUserName()

win32api.GetUserNameEx(...) 

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

Adam
quelle
30
Diese Antwort ist mindestens so nützlich wie die (nutzlose) 25-Stimmen-Unix-Antwort.
Tom B
3
> "Mindestens genauso nützlich" Einverstanden. Vermutlich ist die richtige Antwort eine Kombination aus beiden.
Jonathan Hartley
Wenn Sie unter Windows mit Python 2 nicht weiterkommen, ist dies der einzig sichere Weg. Alle anderen Möglichkeiten können ausgetrickst werden, indem Sie SET USERNAME=FAKEvor Ihrem Python-Befehl
ausführen
21

Wenn Sie dies benötigen, um das Home-Verzeichnis des Benutzers abzurufen, kann das folgende Verzeichnis als portabel (mindestens Win32 und Linux) als Teil einer Standardbibliothek betrachtet werden.

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

Sie können diese Zeichenfolge auch analysieren, um nur die letzte Pfadkomponente (dh den Benutzernamen) abzurufen.

Siehe: os.path.expanduser

HezniK
quelle
9
Das Home-Verzeichnis einer Person spiegelt nicht immer ihren Benutzernamen wider.
Dreamlax
Dies funktioniert sowohl unter Linux als auch unter Windows
Sabrina
Wenn Sie die HOME-Variable in Windows festlegen, wird dieser Wert leider zurückgegeben.
GLRoman
15

Für mich ossieht die Verwendung des Moduls für die Portabilität am besten aus: Funktioniert am besten unter Linux und 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]           

Ausgabe:

Windows:

Home des Benutzers Dir: C: \ Users \ myuser

Benutzername: myuser

Linux:

Home des Benutzers Dir: / root

Benutzername: root

Es müssen keine Module oder Erweiterungen installiert werden.


quelle
16
Diese Lösung ist clever, macht jedoch einige Annahmen, die nicht immer zutreffen. Es gibt keine Einschränkung, nach der der Benutzername unter Linux im Pfad homedir angezeigt werden muss. Es ist die meiste Zeit nur der Fall, aber ein Systemadministrator kann das Homedir eines Benutzers auf das einstellen, was er will.
Joe Holloway
Das Setzen der HOME-Variablen verhindert dies.
GLRoman
11

Kombiniert pwdund getpassAnsatz, basierend auf anderen Antworten:

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
quelle
9

Zumindest unter UNIX funktioniert das ...

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

edit: Ich habe es gerade nachgeschlagen und das funktioniert unter Windows und UNIX:

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

Unter UNIX wird Ihr Benutzername zurückgegeben, unter Windows jedoch die Gruppe, der Schrägstrich und der Benutzername Ihres Benutzers.

- -

IE

UNIX gibt zurück: "Benutzername"

Windows gibt zurück: "Domain / Benutzername"

- -

Es ist interessant, aber wahrscheinlich nicht ideal, es sei denn, Sie tun sowieso etwas im Terminal ... in diesem Fall würden Sie es wahrscheinlich zuerst verwenden os.system. Zum Beispiel musste ich vor einiger Zeit meinen Benutzer zu einer Gruppe hinzufügen, also tat ich es (das ist unter Linux, wohlgemerkt)

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"

Ich denke , das ist einfacher zu lesen und Sie müssen weder pwd noch getpass importieren.

Ich habe auch das Gefühl, dass "Domain / Benutzer" in bestimmten Anwendungen unter Windows hilfreich sein könnte.

dylnmc
quelle
1
Windows kehrt domain/user nicht zurückgroup/user
RealHowTo
4
Das Befehlsmodul funktioniert unter Windows nicht. Es ist ein UNIX-spezifisches Modul (siehe docs.python.org/2/library/commands.html ). Es ist jetzt veraltet und stattdessen wird ein Unterprozess empfohlen. user = subprocess.check_output("whoami").replace("\r\n", "")
ConnectedSystems
k; dann benutze Unterprozess ... jeez
dylnmc
2 Bemerkungen. befehle.whoami hat großartige Arbeit geleistet, selbst im Kontext eines Dienstes, der unter einem anderen Benutzernamen ausgeführt wird. dh mit habe chpst -u nobody python ./manage.py celerycam --pidfile=/var/run/celerycam/celerycam.pid ich niemanden . Zweitens user = subprocess.check_output("whoami").strip() ist portabler als die ersetzen Zeilenvorschübe oben. commandsvs subprocessscheint pingelig, aber Befehle fehlen in Python 3.
JL Peyret
5

Ich habe das PLX-Modul vor einiger Zeit geschrieben, um den Benutzernamen unter Unix und Windows (unter anderem) portabel abzurufen: http://www.decalage.info/en/python/plx

Verwendungszweck:

import plx

username = plx.get_username()

(Es erfordert Win32-Erweiterungen unter Windows)

Abziehbild
quelle
4

Verwenden Sie nur Standard-Python-Bibliotheken:

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

Funktioniert unter Windows, Mac oder Linux

Alternativ können Sie eine Zeile mit einem sofortigen Aufruf entfernen:

from os import environ,getcwd
user = (lambda: environ["USERNAME"] if "C:" in getcwd() else environ["USER"])()
ThisGuyCantEven
quelle
1
getpass ist auch ein Standard lib
jodag
funktioniert nicht für mich in win10, python3.7.4. Es beschwert sich darüber, dass 'USER' nicht in Umgebungsvariablen gefunden wird, denke ich. Ich denke, Getpass ist sowieso eine bessere Wahl.
Rika
3

Sie können den aktuellen Benutzernamen unter Windows über die Windows-API abrufen, obwohl das Aufrufen über die ctypes FFI ( GetCurrentProcessOpenProcessTokenGetTokenInformationLookupAccountSid ) etwas umständlich ist .

Ich habe ein kleines Modul geschrieben, das dies direkt aus Python heraus tun kann, getuser.py . Verwendungszweck:

import getuser
print(getuser.lookup_username())

Es funktioniert sowohl unter Windows als auch unter * nix (letzteres verwendet das pwdModul wie in den anderen Antworten beschrieben).

Michael Kropat
quelle