Is there a portable way to get the current username in Python?
-
20-08-2019 - |
Question
Is there a portable way to get the current user's username in Python (i.e., one that works under both Linux and Windows, at least). It would work like os.getuid
:
>>> os.getuid()
42
>>> os.getusername()
'slartibartfast'
I googled around and was surprised not to find a definitive answer (although perhaps I was just googling poorly). The pwd module provides a relatively easy way to achieve this under, say, Linux, but it is not present on Windows. Some of the search results suggested that getting the username under Windows can be complicated in certain circumstances (e.g., running as a Windows service), although I haven't verified that.
Solution
Look at getpass module
import getpass
getpass.getuser()
'kostya'
Availability: Unix, Windows
p.s. Per comment below "this function looks at the values of various environment variables to determine the user name. Therefore, this function should not be relied on for access control purposes (or possibly any other purpose, since it allows any user to impersonate any other)."
OTHER TIPS
You best bet would be to combine os.getuid()
with pwd.getpwuid()
:
import os
import pwd
def get_username():
return pwd.getpwuid( os.getuid() )[ 0 ]
Refer to the pwd docs for more details:
You can also use:
os.getlogin()
You can probably use:
os.environ.get('USERNAME')
or
os.environ.get('USER')
But it's not going to be safe because environment variables can be changed.
These might work. I don't know how they behave when running as a service. They aren't portable, but that's what os.name
and if
statements are for.
win32api.GetUserName()
win32api.GetUserNameEx(...)
See: http://timgolden.me.uk/python/win32_how_do_i/get-the-owner-of-a-file.html
If you are needing this to get user's home dir, below could be considered as portable (win32 and linux at least), part of a standard library.
>>> os.path.expanduser('~')
'C:\\Documents and Settings\\johnsmith'
Also you could parse such string to get only last path component (ie. user name).
See: os.path.expanduser
To me using os
module looks the best for portability: Works best on both Linux and 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]
Output:
Windows:
User's home Dir: C:\Users\myuser
username: myuser
Linux:
User's home Dir: /root
username: root
No need of installing any modules or extensions.
Combined pwd
and getpass
approach, based on other answers:
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()
For UNIX, at least, this works...
import commands
username = commands.getoutput("echo $(whoami)")
print username
edit: I just looked it up and this works on Windows and UNIX:
import commands
username = commands.getoutput("whoami")
On UNIX it returns your username, but on Windows, it returns your user's group, slash, your username.
--
I.E.
UNIX returns: "username"
Windows returns: "domain/username"
--
It's interesting, but probably not ideal unless you are doing something in the the terminal anyway... in which case you would probably be using os.system
to begin with. For example, a while ago I needed to add my user to a group, so I did (this is in Linux, mind you)
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"
I feel like that is easier to read and you don't have to import pwd or getpass.
I also feel like having "domain/user" could be helpful in certain applications in Windows.
I wrote the plx module some time ago to get the user name in a portable way on Unix and Windows (among other things): http://www.decalage.info/en/python/plx
Usage:
import plx
username = plx.get_username()
(it requires win32 extensions on Windows)
You can get the current username on Windows by going through the Windows API, although it's a bit cumbersome to invoke via the ctypes FFI (GetCurrentProcess → OpenProcessToken → GetTokenInformation → LookupAccountSid).
I wrote a small module that can do this straight from Python, getuser.py. Usage:
import getuser
print(getuser.lookup_username())
It works on both Windows and *nix (the latter uses the pwd
module as described in the other answers).
Using only standard python libs:
from os import environ,getcwd
getUser = lambda: environ["USERNAME"] if "C:" in getcwd() else environ["USER"]
user = getUser()
Works on Windows or Linux
Alternatively, you could remove one line with an immediate invocation:
from os import environ,getcwd
user = (lambda: environ["USERNAME"] if "C:" in getcwd() else environ["USER"])()