unix符号问题的灵感来源于python venv可执行符号链接的使用



问题简要描述

创建venv(通过python -m venv .venv/virtualenv .venv/)后,将创建一个文件树。存在文件.venv/bin/pythonpython3python3.<x>。它是指向/usr/bin/python的unix符号链接。但是这个符号链接是如何与venv的导入搜索路径一起启动的呢?

我的努力

解决这个问题的资源很少。但我做了一些实验:

这两个条目的sys.path值:

对于usrbinpython

>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/lib/python3.10/site-packages']

对于/path/to/venv/bin/python

>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/path/to/venv/lib/python3.10/site-packages']

但是当我创建目录/path/to/empty/并运行ln -s /usr/bin/python /path/to/empty/bin/python时。/path/to/empty的结构如下:

$ tree .
.
├── bin
│   └── python -> /usr/bin/python
└── lib
└── python3.10
└── site-packages

这些子空目录都是手动创建的。

然后当我启动/path/to/empty/bin/python

>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/lib/python3.10/site-packages']

与CCD_ 14和CCD_。

根据我对unix可执行文件的了解,在不提供参数的情况下,可执行文件可以访问的信息是环境变量、当前工作目录(它可以被视为一个特殊的环境变量),而不是其他信息。

在上面的实验中,这些可执行条目在完全相同的bash控制台中启动,没有任何预设的本地环境变量。它似乎也不受当前工作目录的影响(根据/path/to/empty/)。

一般问题

这表明Unix符号链接有一些隐藏的强大功能。这是真的吗?

对于用户来说,符号链接除了硬链接之外还有什么额外的功能。

如果是,如何利用这些强大的功能?

这不是Unix符号链接中某种隐藏的超级能力的产物。当您运行python -m venv .venv/virtualenv .venv/时,您应该会发现已经为您创建了.venv/pyvenv.cfg。当您启动python可执行文件时,它会在初始化期间自动导入site模块。此模块会自动设置您的搜索路径。根据其文件:

如果名为"pyvenv.cfg"的文件存在于sys.executable之上的一个目录中,则会将sys.prefix和sys.exec_prefix设置为该目录,并且还会检查站点包(sys.base_prefix和sys.base_exec_refix将始终是Python安装的"真实"前缀)。如果"pyvenv.cfg"(引导程序配置文件)包含设置为"true"(不区分大小写)以外的关键字"include system site packages",则系统级前缀将不会搜索站点包;否则他们会的。

要演示的一些测试:

/usr/bin/python -c import sys; print(sys.path)导致['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/lib/python3.10/site-packages'],因为python可执行文件上方的目录中不存在pyvenv.cfg文件。

.venv/bin/python -c 'import sys; print(sys.path)'导致['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/path/to/venv/lib/python3.10/site-packages'],因为在正确的位置自动创建了pyvenv.cfg文件,并且site模块找到了它

.venv/bin/python -S -c 'import sys; print(sys.path)'会导致['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/lib/python3.10/site-packages'],因为使用-S会禁用site的自动导入,因此它从不查找pyvenv.cfg

如果删除pyvenv.cfg文件,可以看到site模块不会像以前那样修改搜索路径:.venv/bin/python -c 'import sys; print(sys.path)'(没有-S)会导致['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/lib/python3.10/site-packages']

相关内容

  • 没有找到相关文章