在cron中运行os.getlogin()时出现无效参数

27

如果我创建一个文件:

import os
print os.getlogin()

当我使用cron运行它时,我收到了一个异常

print os.getlogin()
OSError: [Errno 22] Invalid argument
如果我在shell中手动运行它 - 它就可以工作。
问题是,GitPython 0.3.1在commit()中使用了这个函数,而我需要使用它。
是否有任何解决方法?
我已经在Ubuntu10.10 / python2.6.6和Debian5.0.6 / python2.5.2上进行了测试。
4个回答

43

来自 os.getlogin() 文档:“返回进程控制终端登录的用户。” 当您从 cron 运行脚本时,您的脚本没有控制终端。文档建议:“对于大多数情况,更有用的是使用环境变量 LOGNAME 来查找用户,或者使用 pwd.getpwuid(os.getuid())[0] 来获取当前有效用户 ID 的登录名。”

由于您不想修改 GitPython,因此您可以编写一个脚本来执行此操作:

import os, pwd

os.getlogin = lambda: pwd.getpwuid(os.getuid())[0]

import git

# do whatever you need to do with GitPython here

我建议向GitPython提交缺陷报告(最好是提交修补程序)。


是的,这个问题是关于解决方法的。手动编辑外来的包是我最不想做的事情。 - gistart
啊,好的。我已经添加了一个建议来通过猴子补丁os模块来解决这个问题。 - kindall
7
使用 pwd 模块的一个更简单的替代方案可能是 getpass.getuser() - Austin Adams

1

这里是一个未经测试的猜测,可能会起作用的解决方法:os.getlogin() 调用 C 库中的 getlogin(),然后在 utmp 记录中查找与当前进程对应的登录名。由于 cron 没有 utmp 记录,您可以尝试使用以下命令创建一个:

sessreg -a <logname> ; do_stuff ; sessreg -d <logname>

在您的crontab中添加。也许您需要调整sessreg选项。如果您尝试过,请告诉我这是否真正起作用 :)


1
最近我在Docker环境中遇到了同样的问题,由于我无法更改源代码,这个解决方法帮助我解决了问题。 - user3582076

0

我在使用 python:3.7-alpine 镜像在 docker 中运行 Python 程序时遇到了类似的问题。以下是我遇到的问题:

/app/bin # ./util.py 
Traceback (most recent call last):
  File "./util.py", line 58, in <module>
    __auth__ = '/tmp/util-' + os.getlogin() + '.auth'
OSError: unable to determine login name

我通过导出LOGNAME成功规避了这个问题。

 docker run -e LOGNAME  -it --entrypoint /bin/sh b7c35f...cef2738 

0

使用getpass.getuser()函数

适用于Unix和Windows系统。请参阅文档。

从环境变量或密码数据库中获取用户名。

首先尝试各种环境变量,然后再尝试密码数据库。 只要在Windows上设置了USERNAME变量,这个函数就可以工作。

来自Python的os.login()文档:

返回进程所在控制终端上登录的用户名称。 对于大多数情况而言,更有用的是使用getpass.getuser()函数, 因为它会检查环境变量LOGNAME或USERNAME来确定用户身份, 并在需要时回退到pwd.getpwuid(os.getuid())[0]以获取当前实际用户ID的登录名。


如果一个图书馆正在使用它,就像OP的情况一样。正如@kindall所提到的:
import os, getpass

os.getlogin = lambda: getpass.getuser()

# The rest of your code

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