从python venv可执行符号链接的使用中得到启发的unix符号问题

vdzxcuhz  于 2023-01-08  发布在  Unix
关注(0)|答案(1)|浏览(185)

问题简要描述

创建venv后(通过python -m venv .venv/virtualenv .venv/),将创建一个文件树。有一个文件.venv/bin/pythonpython3python3.<x>。它是一个到/usr/bin/python的unix符号链接。但如何使用venv的导入搜索路径启动此符号链接?
∮我的努力∮
解决这个问题的资源很少,但我做了一些实验:
这两个条目的sys.path值:
对于\usr\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']

对于/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']

/usr/bin/python/path/to/empty/bin/python相比没有差异。
根据我对unix可执行文件的了解,在不提供参数的情况下,可执行文件可以访问的信息只有环境变量、当前工作目录(可以看作是一个特殊的环境变量),没有其他信息。
在上面的实验中,这些可执行项在完全相同的bash控制台中启动,没有任何预设的本地环境变量,并且似乎也不受当前工作目录的影响(根据/path/to/empty/)。

一般问题

这说明Unix符号链接隐藏了一些强大的特性,是真的吗?
对于用户来说,符号链接有哪些超出硬链接的额外功能.
如果是,如何利用这些强大的功能?

ykejflvf

ykejflvf1#

这并不是Unix符号链接中隐藏的超级能力的产物,当你运行python -m venv .venv/virtualenv .venv/时,你会发现.venv/pyvenv.cfg已经为你创建好了,当你启动python可执行文件时,它会在初始化过程中自动导入site模块,这个模块会自动设置你的搜索路径,根据它的documentation
如果名为“pyvenv.cfg”的文件存在于sys.executable之上的目录中,sys.prefix和sys.exec_prefix被设置为该目录,并且还检查该目录是否存在站点包(sys.base_prefix和sys.base_exec_prefix将始终是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']

相关问题