有没有一种在Python中获取当前用户名的便携方式?

754

如何以一种跨平台的方式(例如在Linux和Windows上)获取当前用户的用户名?类似于os.getuid()的东西会很不错:

有什么一种可以跨平台使用的方法,能够获取当前用户的用户名吗?希望这个方法在Linux和Windows系统上都能使用,并且类似于os.getuid()的操作。

>>> os.getuid()
42

# Does not currently exist in Python
>>> os.getusername()
'slartibartfast'

pwd模块仅适用于Unix系统。一些人建议在某些情况下(例如作为Windows服务运行时),在Windows下获取用户名可能会很复杂。


它在我的Linux系统上无法运行! - Riccardo
6
import pwd, os; print pwd.getpwuid(os.getuid()).pw_gecosimport pwd, os; print pwd.getpwuid(os.getuid()).pw_name以上两行代码的意思是:导入pwd和os模块,获取当前用户ID并打印出该用户的个人资料或用户名。 - chown
getusername() 不是 os Python 模块中的有效方法:https://docs.python.org/2.7/library/os.html - Matt Bruzek
25
@MattBruzek 那是OP的观点。他在想象如果这样的功能存在,它将如何被调用。 - poke
2
“用户名”甚至不是一个可移植的“概念”。考虑使用microPython-如果您直接在硬件上运行,就没有这样的东西。 - Charles Duffy
给Slartibartfast点赞 - Nick.McDermaid
15个回答

1060

请查看getpass模块。

import getpass
getpass.getuser()
'kostya'

可用性:Unix,Windows


p.s. 根据下面的评论“这个函数查看各种环境变量的值来确定用户名。因此,不能依靠此函数进行访问控制(或可能任何其他目的),因为它允许任何用户冒充任何其他用户。


40
getpass.getuser() 没有问题,因为它并不声明对用户进行身份验证。该函数的目的是在不直接询问用户的情况下确定用户声称的身份。 - Walker Hale IV
9
如果您已经使用了 su 命令,则这种方法行不通。 $ echo $USER hithwen $ su julia 密码: $ echo $USER julia $ python
import getpass getpass.getuser() 'hithwen'
- hithwen
8
@GregHewgill提出了一个非常好的观点,但事实上,像这样以一种简单的未经身份验证的方式找到用户名确实有一些应用。我的当前用例:使用用户名标记一些共享的测试资源,以便稍后轻松清理。(这样更容易弄清楚谁的混乱是谁的。) - floer32
22
我同意@GregHewgill关于访问控制目的的观点,但完全不同意“任何其他目的” - 这就像说“不要在shell脚本中使用$USER”。虽然访问控制方面的观点很好,但还有很多其他用途与身份验证无关。 - nevelis
3
明白,翻译如下:这是按预期工作的。它取决于您给su命令提供的参数。也许你想使用su - julia命令。 - kasperd
显示剩余12条评论

167

结合os.getuid()pwd.getpwuid()

import os
import pwd

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

请参阅pwd文档以获取更多详细信息。


78
另外一种写法(读起来更友好):pwd.getpwuid(os.getuid()).pw_name - Brian M. Hunt
8
在Windows上它的作用是什么?也许可以尝试这样做,如果失败了,就回退到糟糕的“getpass/env var”方法。 - Jonathan Hartley
9
导入错误:没有名为 pwd 的模块。 - Justin
3
在类Unix系统中,这种方法比Konstantin Tenzin的答案要优越得多,因为它可以正确地处理sudo情况。(我知道OP没有要求Unix系统。) - halloleo
3
错误的答案 -- 这不是可移植到Windows的。 - Stabledog
显示剩余2条评论

127

你也可以使用:

os.getlogin()

41
在Linux系统中,getlogin()函数返回“进程所在的控制终端上登录的用户”的名称。因此,当没有控制终端时(例如在mod_python应用程序中),它将失败。 - Vebjorn Ljosa
8
如果您使用了su命令,那么这将不会返回当前用户,而是最初登录的用户。 - Trevor Allred
5
能够在Windows上使用...Python 3.4.1(v3.4.1:c0e311e010fc,2014年5月18日,10:38:22)[MSC v.1600 32位(Intel)] 在win32 上运行。 输入“help”、“copyright”、“credits”或“license”获取更多信息。
import os; os.getlogin() 'jrb'
- Naib
7
只有在Windows平台上才能运行Python 3.x版本。 - Zitrax
3
谢谢。登录用户并不完全符合张贴者的要求,但却是我所需要的。 - jorfus
显示剩余3条评论

108

Windows:

->

Windows操作系统:

os.environ.get('USERNAME')

Linux:

os.environ.get('USER')

两者都:

os.environ.get('USER', os.environ.get('USERNAME'))

请注意,用户可以修改环境变量,因此这是一个潜在的安全漏洞。使用这种方法,攻击者可以轻松地伪造他们的用户名。


27
os.getenv(...)已经被弃用,推荐使用os.environ[...]。请注意保持原有功能不变,仅需翻译,不提供解释或其他内容。 - Mike Graham
12
应该使用"用户"而不是"用户名"吗? - Karl Bartel
10
os.getenv 似乎没有被废弃,对吗? - dbr
5
没错,确实是USER与USERNAME的不可移植性导致它们不能提供正确答案。 - Peter M
8
"USERNAME"用于Windows系统,"USER"用于Linux系统。 - user9013730
显示剩余4条评论

25

38
这个回答至少和那个(毫无用处)得到25个赞的仅适用于UNIX系统的回答一样有用。 - Tom B
5
“至少同样有用”同意。可以假设正确答案是两者的结合。 - Jonathan Hartley
1
如果你在Windows上被困在Python 2上,这是唯一安全的方法。 所有其他方法都可以通过在Python命令之前运行 SET USERNAME=FAKE 来欺骗。 - MathKid

24

如果您需要获取用户的主目录,下面的代码可以被视为可移植的(至少在win32和linux上),它是标准库的一部分。

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

你也可以解析这样的字符串,以仅获取最后一个路径组件(即用户名)。

参见:os.path.expanduser


12
有些情况下,某人的个人目录并不一定反映他们的用户名。 - dreamlax
不幸的是,在Windows中设置HOME变量将返回该值。 - GLRoman

18

psutil提供了一种可移植的方式,不像getpass解决方案那样使用环境变量。它更不容易出现安全问题,可能应该作为今天被接受的答案。

import psutil

def get_username():
    return psutil.Process().username()

在内部,这将结合基于getpwuid的Unix方法和基于GetTokenInformation的Windows方法。


有没有一个函数可以获取它而不带域名,还是我需要在“/”上进行分割? - CeePlusPlus
如果存在“\”,则拆分,是的,请参见:https://github.com/giampaolo/psutil/issues/1049 - Erik Aronesty

17
在我看来,使用os模块是最具可移植性的选择:在Linux和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]           

输出:

Windows:

用户主目录:C:\Users\myuser

用户名:myuser

Linux:

用户主目录:/root

用户名:root

无需安装任何模块或扩展。


26
这个解决方案很聪明,但做了一些并非总是正确的假设。Linux上并没有强制要求用户名出现在homedir路径中的限制。这只是大多数情况下的情况,但系统管理员可以将用户的homedir设置为任何他们想要的内容。 - Joe Holloway
1
设置HOME变量可以解决这个问题。 - GLRoman

15

基于其他答案的结合了pwdgetpass方法:

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()

getpass.getuser() 从环境变量 LOGNAME、USER、LNAME 和 USERNAME 中按顺序检索非空字符串。如果没有设置,则在支持 pwd 模块的系统上返回密码数据库中的登录名,否则会引发异常。pw_name 也是登录名。 - Abhijeet
我可能只使用 pwd 命令,但这是这里唯一能够获取_effective_用户ID名称的答案。 - neuralmer

7

仅使用标准的Python库:

from os import environ
from sys import platform

def getUser():
    return environ["USERNAME"] if platform.startswith("win") else environ["USER"]

user = getUser()

适用于Windows、Mac或Linux操作系统。

2
getpass 也是标准库。 - jodag
在我的Win10系统上,Python3.7.4无法正常工作。它抱怨环境变量中找不到“USER”。我猜getpass可能是更好的选择。 - Hossein
唯一可能导致这种情况的原因是您从非“C:”驱动器运行它。这是使用“USER”键而不是“USERNAME”的唯一原因。这只是一个if / else语句...它所做的就是如果有“C:”驱动器,则使用“USERNAME”,否则使用“USER”。 - ThisGuyCantEven
这只是一个临时解决方案,如果您的当前工作目录在另一个驱动器上,它将会失效。您的答案并没有比其他答案提供更多的好处。即使您想走这条路,也有更好的方法来检查平台,但通常最好从一开始就使用可移植的东西。 - alexia
1
@Rob Grant 很好的编辑 - ThisGuyCantEven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接