虚拟环境中的引用损坏

251

我最近在我的 Mac 上安装了一堆 dotfiles 和其他应用程序(我改用 iTerm 代替 Terminal,并将 Sublime 设置为默认文本编辑器),但自从那时起,我的所有虚拟环境都停止工作了,尽管它们在 .virtualenvs 文件夹内仍然存在,但每当我尝试在其中运行任何内容时,它们都会给出以下错误:

dyld: Library not loaded: @executable_path/../.Python
  Referenced from: /Users/[user]/.virtualenvs/modclass/bin/python
  Reason: image not found
Trace/BPT trap: 5

我已经删除了与dotfiles相关的所有文件,并将我的.bash_profile还原为之前的状态,但问题仍然存在。有没有办法诊断问题或以简单的方式解决它(例如,不需要重新创建所有虚拟环境)?


1
可能相关:http://debugfix.com/2011/11/dyld-library-loaded-executable_path-python/ - unutbu
感谢您的评论,@unubtu。这确实很有帮助。但是我也无法创建任何新的虚拟环境。我的 rmvirtualenv 仍然有效,但是当尝试运行 mkvirtualenv 时,我会收到以下错误:`-bash: /usr/local/bin/virtualenv: /usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/Resour: bad interpreter: No such file or directory`因此,似乎存在我的 Python 路径问题,但我看不到问题所在,因为我可以运行 Python,而且它似乎很正常。 - oxtay
1
[更新] 我可能已经找到了问题,但我不确定该如何解决。理论上,所有的 virtualenv 命令都可以工作,但由于 Python 存在问题,它们并没有起到任何作用。所以真正的问题在于 brew 的 Python。我怀疑原因是 Python 目录名称的更改。由于某种原因,所有这些命令都在寻找 /usr/local/Cellar/python/2.7.6 文件夹中的 Python,但实际上文件夹的名称是 /usr/local/Cellar/python/2.7.6_1 - oxtay
由于我是个新手,我不知道手动将名称从2.7.6_1更改为2.7.6会有多大的风险,也不知道会发生什么。 - oxtay
不幸的是,损坏的链接对我没有起作用。通过@oxtay的解决方案,我能够解决“错误的解释器”问题,方法是创建一个名为/usr/local/Cellar/python/2.7.6的新目录(mkdir),并将/usr/local/Cellar/python/2.7.9中的所有文件复制(cp -r)到该文件夹中。我太紧张了,不敢只是重命名文件夹! - Patrick Williams
显示剩余2条评论
26个回答

388
我在这里找到了解决问题的方法所以所有的功劳归于作者。
要点是,在创建一个虚拟环境时,会创建许多指向Homebrew安装的Python的符号链接。
以下是一个例子:
$ ls -la ~/.virtualenvs/my-virtual-env
...
lrwxr-xr-x  1 ryan staff   78 Jun 25 13:21 .Python -> /usr/local/Cellar/python/2.7.7/Frameworks/Python.framework/Versions/2.7/Python
...
еҪ“дҪ дҪҝз”ЁHomebrewеҚҮзә§Python并иҝҗиЎҢ`brew cleanup`ж—¶пјҢиҷҡжӢҹзҺҜеўғдёӯзҡ„з¬ҰеҸ·й“ҫжҺҘдјҡжҢҮеҗ‘дёҚеҶҚеӯҳеңЁзҡ„и·Ҝеҫ„пјҲеӣ дёәHomebrewе·Іе°Ҷе®ғ们еҲ йҷӨпјүгҖӮ
иҝҷдәӣз¬ҰеҸ·й“ҫжҺҘйңҖиҰҒжҢҮеҗ‘ж–°е®үиЈ…зҡ„Pythonпјҡ
lrwxr-xr-x  1 ryan staff   78 Jun 25 13:21 .Python -> /usr/local/Cellar/python/2.7.8_1/Frameworks/Python.framework/Versions/2.7/Python
解决方法是删除virtualenv中的符号链接,然后重新创建它们:
find ~/.virtualenvs/my-virtual-env/ -type l -delete
virtualenv ~/.virtualenvs/my-virtual-env

在删除链接之前,最好先检查哪些链接将被删除:

find ~/.virtualenvs/my-virtual-env/ -type l

在我看来,仅删除损坏的符号链接甚至更好。您可以使用GNU find来执行此操作:

gfind ~/.virtualenvs/my-virtual-env/ -type l -xtype l -delete
您可以使用Homebrew安装GNU find,如果您还没有它的话:
brew install findutils

请注意,默认情况下,通过Homebrew安装的GNU程序往往会以字母


4
+1 gfind 很完美,因为我有很多未中断的符号链接(例如nodeenv),我不想删除它们。 - 2Toad
4
另一种去除损坏符号链接的方法是使用标准的 find 命令:find -L ~/.virtualenvs/my-virtual-env/ -type l | xargs rm - vdboor
这些步骤对我来说并没有完全起作用:pip3 freeze dyld:lazy symbol binding failed: Symbol not found: __Py_UnixMain - deed02392
1
只是补充一下,如果环境使用的是Python 2,请使用参数运行它:virtualenv ~/.virtualenvs/foo -p python2,否则它会使用Python 3。 - Bohumir Zamecnik
非常感谢。删除符号链接并重新创建虚拟环境解决了问题。干得好。 - user2233949
显示剩余3条评论

44

在尝试了一些方法后,这个对我奏效:

前往您的虚拟环境目录(但不要运行workon):

cd ~/.virtualenv/name_of_broken_venv

现在删除这些文件:

rm -rf .Python bin/python* lib/python2.7/* include/python2.7

然后重新构建您的虚拟环境,请运行:

virtualenv .
workon name_of_broken_venv
pip freeze

现在您应该再次看到您安装的软件包列表。


顺便说一句,我刚刚尝试了这种方法,在升级到El Capitan并重新安装homebrew后,我的软件包列表没有被保留。 - Ryan
1
使用pipenv,您可以通过执行pipenv --rm来删除并重新创建环境,使用pipenv shell进入虚拟环境,使用pipenv install安装依赖包。 - Harry Moreno
如果你遇到了与 virtualenvwrapper.sh: There was a problem running the initialization hooks 相关的错误,你需要执行 pip install virtualenv virtualenvwrapper 或者 pip3 install virtualenv virtualenvwrapper 来重新同步所有内容。 - cybertoast

16

我从Snow Leopard升级到Mac OS X Mavericks时遇到了这个问题。我需要在更新之前重新安装brew。希望您已经对pip的项目运行了freeze命令。

要解决这个问题,您需要更新虚拟环境指向的路径。

  • 使用brew安装Python:

brew install python

  • 重新安装virtualenvwrapper:

pip install --upgrade virtualenvwrapper

  • 删除旧虚拟环境:

rmvirtualenv old_project

  • 创建新的虚拟环境:

mkvirtualenv new_project

  • 使用新的虚拟环境:

workon new_project

  • 使用pip为新项目安装所需的库。

pip install -r requirements.txt

这样做应该会使项目恢复原状。


这是一段时间以前的事情了,我相信最终我做了类似的事情,但由于当时我没有运行 'pip freeze > requirements.txt',所以它不是最有效的解决方案。吸取了教训。 - oxtay

13

@Chris Wedgwood的一个更新版本,用于保留site-packages(保留已安装的软件包)

cd ~/.virtualenv/name_of_broken_venv


mv lib/python2.7/site-packages ./    
rm -rf .Python bin lib include
virtualenv .
rm -rf lib/python2.7/site-packages
mv ./site-packages lib/python2.7/

1
这已经超越完美了。它可以帮助迁移Python版本并保留所有软件包。如果您正在遵循此操作,请不要执行@Chris Wedgewood的指示。 - Harish Prasanna

11

似乎解决此问题的正确方法是运行:

 pip install --upgrade virtualenv

在使用Homebrew升级Python之后,按照以下步骤操作即可。这些步骤适用于任何需要安装像Python这样拥有自己的软件包管理系统的公式。当你执行brew install python命令时,你会安装pythonpipeasy_installvirtualenv等工具。因此,如果这些工具可以自行更新,最好尝试自行更新它们,而不是将Homebrew作为问题源头。


这对于setuptools的问题有效,具体来说是:警告:无法找到setuptools == 0.6c12dev-r88846的svn位置。 - Robert Brisita
1
我采用了这个解决方案,然后在我的破损虚拟环境中运行了以下命令:virtualenv .更新后的 virtualenv 版本重新创建了必要的依赖项,然后一切都正常了。对我来说,这个过程比被接受的答案更自主和健壮。 - christang
1
在2020年,这仍然是答案。 - scubabuddha

7
如果这是由于brew upgrade升级了Python引起的,并且您打算降级到先前的版本,请尝试brew switch python [previous version],例如brew switch python 3.6.5。详情请见此处

5

任何使用pipenv(你应该使用!)的人都可以直接使用这两个命令,无需启用虚拟环境:

rm -rf `pipenv --venv` # remove the broken venv
pipenv install --dev   # reinstall the venv from pipfile 

1
你也可以在你的环境文件夹中使用 pipenv --rm 命令,然后执行 pipenv install --dev 安装依赖。 - Handfeger

3

virtualenvwrapper指南

如接受的答案所示,根本原因可能是homebrew更新导致您的虚拟环境符号链接指向损坏的python路径 - 详情请参见此处

对于每个虚拟环境,您需要重新分配符号链接以指向正确的python路径(在brew cellar中)。以下是使用virtualenvwrapper的方法。这里我正在更新名为“my-example-env”的虚拟环境。

cd ~/PYTHON_ENVS
find ./my-example-env -type l -delete
mkvirtualenv my-example-env

所有操作完成。


不可移植(BSD find) - sorin

2
我的问题是(brew)更新了Python和虚拟环境的链接到已删除的旧版本,这对我(一名MacOS用户)来说是个问题。
我们可以通过以下方式检查并修复它:
>> ls -al ~/.virtualenvs/<your-virtual-env>/.Python
.Python -> /usr/local/Cellar/python/<old-version>/Frameworks/Python.framework/Versions/3.7/Python
>> rm ~/.virtualenvs/<your-virtual-env>/.Python
>> ln -s  /usr/local/Cellar/python/<new-version>/Frameworks/Python.framework/Versions/3.7/Python ~/.virtualenvs/<your-virtual-env>/.Python

这也适用于在已安装Python3.6的系统上安装Python 3.7后修复损坏的链接。 - lukik

2

我遇到了类似的问题,只需使用 virtualenv . 重新构建虚拟环境即可解决问题。


欢迎来到SO。虽然我们感谢您的回答,但如果它在其他答案的基础上提供了额外的价值,那么就更好了。在这种情况下,由于另一位用户已经发布了那个解决方案,因此您的答案并没有提供附加值。如果以前的答案对您有帮助,您应该在获得足够的声望后投票支持它 - David Buck

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