是否有可移植的方式来获取Python中的当前用户名?

Jac*_*son 575 python portability username

是否有一种可移植的方式来获取Python中当前用户的用户名(即,至少在Linux和Windows下都能运行的用户名).它的工作方式如下os.getuid:

>>> os.getuid()
42
>>> os.getusername()
'slartibartfast'
Run Code Online (Sandbox Code Playgroud)

我搜索了一下,并且惊讶地发现没有找到确定的答案(尽管我可能只是谷歌搜索不好).该PWD模块提供了一个相对简单的方法来实现这一目标下,说,Linux的,但它不存在于Windows.一些搜索结果表明,在Windows下获取用户名在某些情况下可能会很复杂(例如,作为Windows服务运行),尽管我还没有验证.

Kon*_*zin 787

看看getpass模块

import getpass
getpass.getuser()
'kostya'
Run Code Online (Sandbox Code Playgroud)

可用性:Unix,Windows


ps以下评论" 此函数查看各种环境变量的值以确定用户名.因此,不应依赖此函数用于访问控制目的(或可能是任何其他目的,因为它允许任何用户冒充任何其他用户). "

  • 看来这个函数会查看各种环境变量的值来确定用户名.因此,不应依赖此功能用于访问控制目的(或可能是任何其他目的,因为它允许任何用户冒充任何其他用户). (97认同)
  • getpass.getuser()没有任何问题,因为它没有声明对用户进行身份验证.该功能的目的是确定用户声称是谁而不直接询问用户. (21认同)
  • 我同意@GregHewgill的访问控制目的,但完全不同意"任何其他目的" - 就像说"不要在shell脚本中使用$ USER".关于访问控制的重点,但有很多其他用途不涉及auth. (15认同)
  • 如果你做了su,这不起作用.$ echo $ USER hithwen $ su julia密码:$ echo $ USER julia $ python >>> import getpass >>> getpass.getuser()'hithwen' (7认同)
  • @GregHewgill提出了一个非常好的观点,但实际上,以一种简单的未经验证的方式找到用户名就像这样有一些应用程序.我目前的用例:使用用户名标记一些共享测试资源,以便以后轻松清理.(所以更容易弄清楚哪个是谁的混乱.) (6认同)
  • @hithwen那是按预期工作的.这取决于你给`su`的论据.也许你想用'su - julia`. (2认同)

小智 104

您最好的选择是结合os.getuid()使用pwd.getpwuid():

import os
import pwd

def get_username():
    return pwd.getpwuid( os.getuid() )[ 0 ]
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅pwd文档:

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

  • 在Windows上不起作用(如原始问题中所述) (60认同)
  • 或者(稍微好一点):`pwd.getpwuid(os.getuid()).pw_name`. (42认同)
  • 它在Windows上做了什么?也许有人可以试试这个,如果它失败了,可以回到糟糕的'getpass/env var'方法. (6认同)
  • @JonathanHartley:`ImportError: No module named pwd` (6认同)
  • 错误答案——这不能移植到 Windows。 (3认同)
  • 如果您需要同时登录和不登录都需要获取用户名,这是正确的方法。 (2认同)
  • 这种方法在类 UNIX 系统上**远**优于 Konstantin Tenzin 的答案,因为它可以正确处理“sudo”情况。(我知道OP没有要求类似unix的系统。) (2认同)

小智 78

您还可以使用:

 os.getlogin()
Run Code Online (Sandbox Code Playgroud)

  • 在linux上,getlogin()返回"在进程的控制终端上登录的用户"的名称.因此,当没有控制终端时,例如在mod_python应用程序中,它就会失败. (28认同)
  • 不适用于Windows (22认同)
  • 它仅适用于Windows for Python 3.x. (5认同)
  • 在Windows上工作... Python 3.4.1(v3.4.1:c0e311e010fc,2014年5月18日,10:38:22)[MSC v.1600 32位(英特尔)]在win32上输入"help","copyright", "信用"或"许可"以获取更多信息.>>> import os; os.getlogin()'jrb' (4认同)
  • 如果你使用su,那么这将不会返回当前用户,而是返回最初登录的用户. (3认同)
  • 谢谢你。登录用户并不完全是发帖者所要求的,但它正是我正在寻找的。 (3认同)

Nad*_*mli 64

你可以使用:

os.environ.get('USERNAME')
Run Code Online (Sandbox Code Playgroud)

要么

os.environ.get('USER')
Run Code Online (Sandbox Code Playgroud)

但它不会安全,因为环境变量可以改变.

  • 不推荐使用`os.getenv(...)`来支持`os.environ [...]`. (17认同)
  • 不应该是USER而不是USERNAME吗? (10认同)
  • @MikeGraham [`os.getenv`](http://docs.python.org/dev/library/os.html#os.getenv)似乎不被弃用..? (7认同)
  • 是(至少在Linux下)它只是:`os.getenv('USER')` (7认同)
  • USERNAME 用于 Windows,USER 用于 Linux (6认同)
  • 是的,确切地说USER和USERNAME正是不可移植的,所以它没有提供正确的答案. (3认同)

小智 21

这些可能有效.我不知道他们作为服务运行时的行为方式.它们不可移植,但这就是"os.name"和"if"语句的用途.

win32api.GetUserName()

win32api.GetUserNameEx(...)

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

  • 这个答案至少与(无用的)25票投票支持unix的答案一样有用. (29认同)
  • >"至少同样有用"同意.大概正确的答案是两者的结合. (2认同)

小智 20

如果你需要这个来获得用户的家庭目录,下面可以被认为是便携式的(至少是win32和linux),是标准库的一部分.

>>> os.path.expanduser('~')
'C:\\Documents and Settings\\johnsmith'
Run Code Online (Sandbox Code Playgroud)

您还可以解析此类字符串以仅获取最后一个路径组件(即用户名).

请参阅:os.path.expanduser

  • 某人的主目录并不总是反映他们的用户名. (5认同)

小智 16

对我来说,使用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]           
Run Code Online (Sandbox Code Playgroud)

输出:

视窗:

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

用户名:myuser

Linux的:

用户的主页目录:/ root

用户名:root

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

  • 这个解决方案很聪明,但做出一些并非总是如此的假设.没有约束要求用户名出现在Linux上的homedir路径中.大多数情况下恰好就是这种情况,但系统管理员可以将用户的homedir设置为他们想要的任何内容. (14认同)

ana*_*nik 11

结合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()
Run Code Online (Sandbox Code Playgroud)


dyl*_*nmc 8

对于UNIX,至少,这有效......

import commands
username = commands.getoutput("echo $(whoami)")
print username
Run Code Online (Sandbox Code Playgroud)

编辑: 我只是查找它,这适用于Windows和UNIX:

import commands
username = commands.getoutput("whoami")
Run Code Online (Sandbox Code Playgroud)

在UNIX上,它返回您的用户名,但在Windows上,它会返回您的用户组,斜杠,您的用户名.

-

IE

UNIX返回:"username"

Windows返回:"域/用户名"

-

这很有趣,但可能不理想,除非你在终端做某事......在这种情况下你可能会os.system开始使用.例如,前一段时间我需要将我的用户添加到一个组中,所以我做了(这是在Linux中,请注意)

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"
Run Code Online (Sandbox Code Playgroud)

我觉得这样更容易阅读,你不必导入pwd或getpass.

我也觉得让"域/用户"在Windows中的某些应用程序中有所帮助.

  • 命令模块在Windows上不起作用.它是一个特定于UNIX的模块(请参阅https://docs.python.org/2/library/commands.html).它现在已弃用,建议使用子流程.`user = subprocess.check_output("whoami").replace("\ r \n","")` (4认同)
  • WIndows 返回“域/用户”而不是“组/用户” (2认同)

Eri*_*sty 8

psutil提供了一种可移植的方式,它不像getpass解决方案那样使用环境变量。它不太容易出现安全问题,现在应该是公认的答案。

import psutil

def get_username():
    return psutil.Process().username()
Run Code Online (Sandbox Code Playgroud)

在幕后,这结合了getpwuid基于 unix 的GetTokenInformation方法和 Windows的方法。


Thi*_*ven 6

仅使用标准 python 库:

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

适用于 Windows(如果您在驱动器 C 上)、Mac 或 Linux

或者,您可以通过立即调用删除一行:

from os import environ,getcwd
user = (lambda: environ["USERNAME"] if "C:" in getcwd() else environ["USER"])()
Run Code Online (Sandbox Code Playgroud)

  • getpass 也是一个标准库 (2认同)

小智 5

我不久前编写了plx模块,以便在Unix和Windows上以便携方式获取用户名(以及其他内容):http: //www.decalage.info/en/python/plx

用法:

import plx

username = plx.get_username()
Run Code Online (Sandbox Code Playgroud)

(它需要Windows上的win32扩展)


Dmi*_* T. 5

以上均不适用于我的情况(向下滚动到实际的解决方案)。
我在所有解决方案中遇到的问题是运行命令时的用户名错误sudo

  • psutil解决方案:
$ python3
>>> import psutil
>>> psutil.Process().username()
'ubuntu' # OK!

$ sudo su
$ python3
>>> import psutil
>>> psutil.Process().username()
'root' # OK!

$ sudo python3
>>> import psutil
>>> psutil.Process().username()
'root' # WRONG, should be ubuntu!
Run Code Online (Sandbox Code Playgroud)
  • getpass解决方案:
$ python3
>>> import getpass
>>> getpass.getuser()
'ubuntu' # OK!

$ sudo su
$ python3
>>> import getpass
>>> getpass.getuser()
'root' # OK!

$ sudo python3
>>> import getpass
>>> getpass.getuser()
'root' # WRONG, should be ubuntu!
Run Code Online (Sandbox Code Playgroud)
  • pwd+os.getuid解决方案:
$ python3
>>> import os, pwd
>>> pwd.getpwuid( os.getuid() )[ 0 ]
'ubuntu' # OK!

$ sudo su
$ python3
>>> import os, pwd
>>> pwd.getpwuid( os.getuid() )[ 0 ]
'root' # OK!

$ sudo python3
>>> import getpass
>>> getpass.getuser()
'root' # WRONG, should be ubuntu!
Run Code Online (Sandbox Code Playgroud)
  • os.getlogin工作方式有点不同,但仍然是错误的:
$ python3
>>> import os
>>> os.getlogin()
'ubuntu' # OK!

$ sudo su
$ python3
>>> import os
>>> os.getlogin()
'ubuntu' # WRONG, should be root!


$ sudo python3
>>> import os
>>> os.getlogin()
'ubuntu' # OK!
Run Code Online (Sandbox Code Playgroud)
  • os.getenv给出相同的结果:
$ python3
>>> import os
>>> os.getenv('SUDO_USER', os.getenv('USER'))
'ubuntu' # OK!

$ sudo su
$ python3
>>> import os
>>> os.getenv('SUDO_USER', os.getenv('USER'))
'ubuntu' # WRONG, should be root!


$ sudo python3
>>> import os
>>> os.getenv('SUDO_USER', os.getenv('USER'))
'ubuntu' # OK!
Run Code Online (Sandbox Code Playgroud)

切换SUDO_USERUSER给出错误的结果以防sudo python3万一。

实际解决方案(非便携式)

解决方案有点棘手,依赖于默认的根主目录位置,但适用于所有情况:

$ python3
>>> import os
>>> 'root' if os.path.expanduser('~') == '/root' else os.getenv('SUDO_USER', os.getenv('USER'))
'ubuntu' # OK!

$ sudo su
$ python3
>>> import os
>>> 'root' if os.path.expanduser('~') == '/root' else os.getenv('SUDO_USER', os.getenv('USER'))
'root' #  OK!

$ sudo python3
>>> import os
>>> 'root' if os.path.expanduser('~') == '/root' else os.getenv('SUDO_USER', os.getenv('USER'))
'ubuntu' # OK!
Run Code Online (Sandbox Code Playgroud)