我试图阻止用户使用 pip 在他们的主目录中安装包。
的输出python3 -m site --help
表明超级用户可以禁用用户站点目录。但是如何做到这一点?我尝试过site.ENABLE_USER_SITE
从中进行设置sitecustomize.py
,但没有帮助。PYTHONNOUSERSITE=1
在环境中设置或传递-s
给 python 有效,但并不完全是超级用户调整。
我也尝试过通过某种方式禁用用户的 pip 来解决这个问题。我们很乐意将软件包安装到 venv 环境中,而不是用户主目录中。我可以输入什么pip.conf
来强制禁用--user
安装。
答案1
问:我可以在 pip.conf 中输入任何内容来强制禁用 --user 安装。
A:否。配置文件始终可以根据pip 文档:
命令行选项优先于环境变量,环境变量又优先于配置文件。
问:超级用户可以禁用用户站点目录。但是如何做到这一点?PYTHONNOUSERSITE=1
在环境中设置或传递-s
给 python 是可行的,但并不完全是超级用户的调整。
A:我通过谷歌想到了这个问题,因为我发现了完全相反的情况——我没有看到PYTHONNOUSERSITE
真正改变 pip 的行为:
$ docker run --net=host -it python:3.8 bash
$ pip install -U pip
Requirement already up-to-date: pip in /usr/local/lib/python3.8/site-packages (20.2.2)
$ ls -ltr ~/.local
ls: cannot access '/root/.local': No such file or directory
$ PYTHONNOUSERSITE=1 pip install --user typing-extensions
Collecting typing-extensions
Downloading typing_extensions-3.7.4.3-py3-none-any.whl (22 kB)
Installing collected packages: typing-extensions
Successfully installed typing-extensions-3.7.4.3
$ ls -ltr ~/.local
total 4
drwxr-xr-x 3 root root 4096 Aug 24 07:08 lib
如果设置了此选项,Python 将不会将用户站点包目录添加到 sys.path。
因此,尽管我对这种行为感到惊讶,但我认为即使设置了这个变量,pip 仍然可以合理地安装PYTHONUSERBASE
(即使结果已安装包将不会在 Python 路径上可用)。
我发现了一个pip 问题跟踪器上的相关问题并且看起来已经存在一个特殊情况,即 venvs 的系统站点包被禁用(默认),不被允许进行用户安装(我没有明确检查这一点)。
因此,根据原始错误报告的解决方案,我们得到了一个拉取请求,其中包含一些有趣的功能也就是说,似乎有一个超级用户可以创建的特殊文件 ````,它禁用用户站点包安装。我还发现了一个关于此问题。所以我尝试了这个,但不幸的是它仍然继续安装到用户群中:
$ touch /usr/local/lib/python3.8/no-global-site-packages.txt
$ pip install --user typing-extensions
...
Successfully installed typing-extensions-3.7.4.3
当然,当我们读到实际的拉取请求实施仅在虚拟环境情况下检查此文件。就我而言,我希望能够总是禁用此行为,因此我将更深入地研究 pip 代码库......
事实证明,关键功能是decide_user_site
, 哪个做尊重site.ENABLE_USER_SITE
价值,但是仅有的在检查了显式user
参数之后。正如我们在函数本身中看到的那样,这与虚拟环境的处理方式不对称,如果虚拟环境已禁用全局/用户安装,这将阻止它们。我认为这是个错误,我已经在https://github.com/pypa/pip/issues/8794。
因此答案是:据我所知,目前无法--user
在基础(即非虚拟)环境中禁用安装。当是可以这样做(希望当上述问题得到解决时)可以使用-s
和PYTHONNOUSERSITE=1
环境变量,但我认为你正在寻找的“系统管理员”方法是修改直接在 site.py 中执行,如 site.py 实现中所述。
答案2
旧线程,但这是可能的解决方案..强制 pip 具有虚拟环境而不是直接安装在用户站点上。
export PIP_REQUIRE_VIRTUALENV=true