Virtualenv: virtualenv的根路径中的空格会破坏脚本

创建于 2011-03-14  ·  59评论  ·  资料来源: pypa/virtualenv

我不太确定这是否是一个distribute / setuptools / virtualenv,但是,

如果我在其中安装virtualenv

/ var / lib / hudson / home / jobs / Minification WebHelpers / workspace / python / 2.4

然后运行./bin/easy_install:

bash:./bin/easy_install:“ / var / lib / hudson / home / jobs / Minification:错误的解释器:没有这样的文件或目录

似乎某些东西不能正确遵守路径名中的空格。


  • Bitbucket: https
  • 最初报道者:DomenKožar
  • 最初创建于:2010-05-07 14:57:32

最有用的评论

正如@JLDH@gandie所确认的,此问题现已解决。 当virtualenv的根目录中有空格时,最新版本的pip和virtualenv可以一起正常工作。

结束了! 感谢您对基础修复@vsajip所做的工作!

所有59条评论

+1,已通过Mac OS X 10.7.3和Python 2.7.1确认

有点烦人,修正一下会很棒

我们能够创建一个名称中带有空格的virtualenv(请参阅#278),但是easy_install和pip稍后会绊倒它:

% virtualenv "foo bar"
New python executable in foo bar/bin/python
Installing setuptools............done.
Installing pip...............done.
% ./foo\ bar/bin/easy_install nose
zsh: ./foo bar/bin/easy_install: bad interpreter: "/tmp/cfl/foo: no such file or directory
127 % ./foo\ bar/bin/pip install nose 
zsh: ./foo bar/bin/pip: bad interpreter: "/tmp/cfl/foo: no such file or directory

我也在这里确认这是OS X的问题(此处为10.8)。 如果您编辑VIRTUAL_ENV变量并在bin中弹出,则可以使其生效,但是路径中的任何空格都会出现新的env阻塞现象。 考虑到引导驱动器通常被命名为“ Macintosh HD”,这对于OS X是一个大问题,因此每个路径都以“ / Volumes / Macintosh HD ...”开头。

我正在使用的技巧如下。

bin /激活:

VIRTUAL_ENV='/Volumes/Macintosh\ HD/path/to/my/project'

bin / pip和bin / easy_install:

#!"/Volumes/Macintosh\ HD/path/to/my/project/venv/bin/python"

退出路径中的空格后,Pip似乎可以正常工作。

为什么关闭了? 这仍然是一个大问题。 编辑我的错误,它仍然打开

此问题仍显示为未解决。

我能够解决这个问题,创建了一个从我的主目录到我要工作的目录的符号链接(否则该目录中有一个空格)。

我也看到这是因为Mac。 我通过手动将脚本中的shebang行编辑为!#/ usr / bin / env python来解决此问题,并且可以完成所有工作。 但是,正如其他人提到的那样,必须使用每个新的环境以及环境中安装的所有其他脚本来完成此操作。
似乎这应该是代码中的一个简单修补程序,可以逸出空间,或者在is_darwin中使用/ usr / bin / env。 但是,由于我对此很不了解,所以我可能是错的。

这不仅适用于Mac,而且基本上是* nix系统规范/行为的一部分。

在shebang行的第一个参数中不能有空格(它们将变成单独的参数),并且通常也不允许转义/引用。

http://lists.gnu.org/archive/html/bug-bash/2008-05/msg00053.html

我知道,我也遇到了Anaconda这个问题。 这只是Mac的特有现象,因为驱动器名称中包含空格。

看来这将由#611纠正。 有没有审查该请求的效力?

如此烦人,应尽快修复。

请参阅发布的链接@Ivoz ,这是Unix的限制。 #611对于某些Unix变体,如果它们在shebang行中支持反斜杠转义,则可能适用,但尚不清楚哪个版本可以(并且代码只是盲目地进行了检查而不作检查-公认这不会使问题“糟透了”,但不会)如果不支持的话也无济于事...)

确实,这是unix处理shebang行的方式的结果,但是,如果#611解决了某些系统的问题,并且没有使其他系统的问题恶化,这是否还会有所改善?

如果是这样,那么是的。 但由于我不是Unix开发人员,所以我无法对#611进行评论。 我只是不知道在某些情况下会使情况变得更糟。 抱歉,我帮不上忙。

很公平。 #611可能需要更仔细地检查并测试边缘情况。

更糟糕的是:在Windows上,它在默认的Jenkins路径上中断,并出现相同的错误:
致命:Python解释器的路径中不允许使用空格:C:\ Program Files(x86)\ Jenkins \ shiningpanda \ jobs \ c3418983 \ virtualenvs \ d41d8cd9

我只是受到这个问题的影响。 按照我在StackOverflow上找到的说明,通过仅将第一行设置为#!/usr/bin/env python ,我设法使pip工作

但是,我不确定该解决方案是否适用于所有情况...我是说,我不确定要执行哪个Python

将已安装脚本的shebang更改为“ env python”意味着它们仅在激活的virtualenv中起作用。 这些脚本是使用显式绝对路径生成的,因此它们将始终在venv中使用Python,从而找到脚本所需的已安装软件包。

我的建议是,某人(可能是受此问题影响的人,但至少是平台上有问题且也有解决问题的方法的某人)提供拉取请求,以实现以下方面的检查:

  • 如果路径名中有空格,
  • 我们在XXX平台上,
  • 然后使用以下转义符写出shebang行以处理空格。
  • 在所有其他情况下,请退回当前的行为。

然后,有兴趣的各方只需添加额外的平台检查,便可以进行其他添加。

理想情况下,最好在注释中包含指向文档的链接,以确认平台XXX如何支持带空格的路径,以便将来的维护者可以参考。 就个人而言,我不清楚哪些修补程序可以工作以及在哪里:

  1. 这里的讨论建议在OSX上使用双引号,但这是否取决于精确的OSX版本?
  2. 在#611中,使用了带反斜杠的转义空格,但没有确认其适用的操作系统(Linux?特定的内核版本?特定的发行版?)。

请注意,任何此类特定于平台的变体都不应使用/usr/bin/env 。 正如@merwok指出的那样,这会导致行为发生变化-故意编写shebang来允许运行脚本而无需激活环境。

添加一些测试以确保行为符合预期(包括当我们不在特定公认的平台上时行为会回退的原理)也是非常有用的,但也很麻烦,因为这涉及到猴子补丁当您实际上不在平台XXX上运行时,允许对其进行测试。

@pfmoore正如我所提到的,我最近受到此问题的影响,并且我正在运行Linux Mint18。我从未为Virtualenv做出过贡献,但是我目前在Python Brasil工作,我们将有一天致力于冲刺,我可能会给予支持试试看!

根据https://lists.gnu.org/archive/html/bug-bash/2008-05/msg00052.html的说法,使用反斜杠或引号转义将不起作用

通过实验,我可以验证使用反斜杠或引号进行转义在OSX 10.11.6中不起作用。

virtualenv应该远离依赖内核的shebang。 我已经检查过Linux,XNU(macOS的内核),FreeBSD,OpenBSD和NetBSD源代码。 他们谁都无法处理舍邦的空间。

在进行修复之前,请勿使用空格。

我提交了一个补丁,该补丁为Python 3的新venv添加了警告,该警告与virtualenv非常相似,但遭到@vsajip拒绝: http : //bugs.python.org/issue28446 确实,这不是Python的错,而是操作系统的错。 也许这个问题可以解决?

作为一个额外的数据点,请注意Windows上的行为,这似乎是预期的:

C:\ Users \ Vinay> \ python34 \ python -m venv“ \ Temp \ aaa bbb”

C:\ Users \ Vinay>“ \ Temp \ aaa bbb \ Scriptspip” --version
来自C:\ Temp \ aaa bbb \ lib \ site-packages的pip 6.0.8(python 3.4)

C:\ Users \ Vinay> pyzzer -i“ \ Temp \ aaa bbb \ Scriptspip.exe”
有一个发射器。
Shebang:#!“ C:\ Temp \ aaa bbb \ Scripts \ python.exe”

存档内容:
__main__.py

C:\ Users \ Vinay>“ \ Temp \ aaa bbb \ Scripts \ python” -m pip install -U pip
您正在使用pip版本6.0.8,但是版本9.0.1可用。
您应该考虑通过“ pip install --upgrade pip”命令进行升级。
https://pypi.python.org/ [...] / pip-9.0.1-py2.py3-none-any.whl#md5 = 297 [...]收集点
使用缓存的pip-9.0.1-py2.py3-none-any.whl
安装收集的软件包:pip
找到现有的安装:pip 6.0.8
卸载pip-6.0.8:
成功卸载了pip-6.0.8

成功安装pip-9.0.1

C:\ Users \ Vinay>“ \ Temp \ aaa bbb \ Scriptspip” --version
来自C:\ Temp \ aaa bbb \ lib \ site-packages(python 3.4)的pip 9.0.1
```

当distlib在PC / launcher.c中定义它自己的shebang协议时,Windows上的Yelp virtualenv脚本就可以工作。 也许POSIX可能有类似的东西-用户空间shebang解析器,而不是不可靠的内核。

用户空间shebang解析器,而不是不可靠的内核

我不确定为什么Bash无法做到这一点(例如)-我不认为这是内核空间的事情。

Shebangs在内核空间中处理,因为它应该在外壳程序之外可用。

技术细节:
在类似UNIX的系统(Linux,Mac,* BSD等)上,将通过fork()和exec()创建一个新程序。 exec()与Windows上的CreateProcess()相似,后者运行一个新程序。 在类似UNIX的系统上,exec()最终调用系统调用execve()。 后一个功能在内核中实现,因此shebang解析在内核中完成。
它也不能在C库中实现,否则静态链接程序或直接使用系统调用(通过int 80或sysenter等)的程序将无法工作。

也许我们应该只是禁止在路径中带有空格的虚拟环境的创建。 反正它不会按预期工作

Shebangs在内核空间中处理,因为它应该在外壳程序中可用

是的,但是如果系统调用返回ENOEXEC外壳程序将无法自行解析? 我意识到这可能是一罐蠕虫...

有趣的花絮-Linux上的内核功能似乎是由长期的Python提交人Martin vonLöwis编写的:-)

此页面也很有趣: http :

是的,但是如果系统调用返回ENOEXEC外壳程序将无法自行解析?

IMO在外壳程序和底层内核之间的不同语义将给用户以及开发人员带来很多混乱。 当前,当execve()失败时,至少bash和zsh会进行解析,但这只是为了更好地报告错误,而不提供回退。

有趣的花絮-Linux上的内核功能似乎是由长期的Python提交人Martin vonLöwis编写的:-)

有趣! 我没有注意到:)也感谢您提供的额外材料。 虽然读取内核源代码是最快的方法,但此类文档仍然很有帮助。

关于@fbidu的想法:

也许我们应该只是禁止在路径中带有空格的虚拟环境的创建。 反正它不会按预期工作

创建具有脆弱路径的虚拟环境对于测试路径处理中的极端情况很有用。 在此示例中,它演示了如何破解内核。 我的想法是添加警告而不是禁止警告,就像我发布到http://bugs.python.org/issue28446的补丁一样

我认为#994“虚拟环境路径中的空间失败导致插页失败”是此问题的重复。

我想重复来自https://github.com/pypa/virtualenv/issues/997#issuecomment -270681253的评论,“ virtualenv被脆弱的内核shebang解析破坏了。” 按照这种精神,#1014“与路径中不包含表情符号的目录不兼容”是虚拟环境被脆弱的内核shebang解析破坏的另一个示例。 我敢打赌,实际上,路径中的任何非ASCII字符都会出现问题。

也许我们应该将易碎的内核shebang的所有三个方面收集到一个问题中,以便我们可以确保一种解决方案可以解决virtualenv路径中的空格,长度和非ASCII字符? 我提名这个问题,因为它是最古老的。

当我们进行修复时,我认为当要求在a)包含空格,b)太长或c)包含非ASCII字符的路径中创建环境时,virtualenv打印警告会很好。 一些文档中的句子也会有所帮助。

我敢打赌,实际上,路径中的任何非ASCII字符都会出现问题。

我相信#1014的原因是在virtualenv中而不是内核中。 我有一个补丁可以解决#900处非常相似的问题。

大家好,
这看起来非常简单(至少是简单的原因),所以非常烦人,而且浪费大量时间。

重命名(如果可能)或使用链接(创建一个没有空间的目录,例如/virtualenvs/python3.5,然后将其作为到原始目录的软链接)怎么样?

创建一个没有空间的目录,例如/virtualenvs/python3.5

另一个项目virtualenvwrapper也做了类似的事情。

看起来很简单的东西(至少是简单原因)。

两者都不简单。 原因与内核解析代码有关,解决方法需要用户空间shebang处理。

六年后仍然是一个问题吗?

这个问题使我两周前绊倒了。 是的,这仍然是一个问题。

请注意,由于这是Unix问题,而不是virtualenv问题,除非取消了Unix内核限制,否则不太可能被“修复”。

第一个virtualenv错误是virtualenv选择通过使用某些Unix内核功能来实现Shell可执行文件,尽管该功能具有通常会给virtualenv用户带来问题的限制。 Virtualenv可以通过对Shell可执行文件使用不同的机制来解决此问题。 第二个virtualenv错误是没有文档说明用户应该如何使用virtualenv来解决第一个错误(仅在具有纯ASCII字符且没有空格的短路径上创建virtualenv)。 第三个virtualenv错误是它没有机制来检测用户选择将触发第一个错误的virtualenv路径并打印有用的警告消息的情况。 virtualenv贡献者可以做很多事情来改善这种情况。

@JDLH关于您的第一个“错误”:它不是由virtualenv处理,而是由distlib处理,并且在https://bitbucket.org/pypa/distlib/pull-requests/31/中有一个实现

virtualenv的第一个错误是virtualenv选择通过使用某些Unix内核功能来实现Shell可执行文件

@JDLH这不是特定于virtualenv -_all_ Unix脚本文件(即带有shebang行的文件)使用此内核功能-并没有令人信服的理由重新发明virtualenv (或其他任何东西)当现有机制被广泛使用和很好理解时,这是一种全新的调度脚本方法。 如果您手动编写的脚本在解释器路径中有空格(不涉及virtualenv ),它将出现相同的问题。

virtualenv贡献者可以做很多事情来改善这种情况。

可能有很多关于贡献者时间的呼吁。 此问题影响使用长路径/带空格的路径的情况相对较少。 也许某些受影响的用户可以通过提出有助于检测和警告消息的补丁来帮助贡献者帮助他们? 只是一个想法。

@ yan12125 distlib允许一个人在shebang行中指定可执行文件。 由于向后兼容,Linux开发人员可能永远不会解决空白/长行上的内核限制。 可以为shebang可执行文件提供一个自定义字符串(并加入与Mozilla脚本hack的通用等效项),然后distlib应该将其写入脚本,因此可以像distlib一样尝试使用它。

这不是特定于virtualenv的

@vsajip这是一个真实的声明—其他软件使用的是virtualenv选择的相同的shebang机制—但它没有解决此问题的重点。 virtualenv提供的价值并没有要求它使用shebang。 virtualenv可以使用其他机制,但是它选择了shebang,因此virtualenv确实继承了shebang的局限性。

没有必要的理由让virtualenv(或其他任何方式)重新发明一种全新的调度脚本方法

我认为您是说,多年来遇到此问题的人们所遇到的问题不是“令人信服的”。 我认为多年来有这么多人发现并评论这个问题的原因是,他们确实发现了“令人信服”的问题。 当然可以

也许某些受影响的用户可以通过提出有助于检测和警告消息的补丁来帮助贡献者帮助他们? 只是一个想法。

我选择了“贡献者”一词,既包括从事virtualenv大部分工作的坚定人士,也包括像我一样的访问者,他们发现这个问题很引人注目,可以减少影响。 可以说,发现问题令人信服的我们应该做出补丁。

如果对virtualenv非常了解的坚定人士可以提出有前途的方法,那将是有帮助的。 如果我想为键入virtualenv ~/my\ long\ path\ with\ spaces的用户插入警告消息,则该代码最好放在哪里? 在这样的补丁上是否存在明显的限制,可以让支持者共享这些限制,以消除访问者进行首次贡献时遇到的障碍? 拥护者是否对接受这样的补丁有一些历史异议? (我的意思是,我不能成为第一个想到添加警告消息的人。必须有一个尚未发生警告的原因。)

有一个众所周知的路径,其中包含空格且无法修改: /Users/iulian/Library/Mobile Documents/com~apple~CloudDocs 。 因此,想要在iCloud中使用virtualenv管理某些脚本的任何人都会遇到此问题。

如果对virtualenv非常了解的坚定人士可以提出有前途的方法,那将是有帮助的。

好吧,如果我们知道的话,考虑到我们似乎为此受到的批评,我们可能不会这么久没有解决这个问题了:-(

如果我想为键入virtualenv〜/ my \ long \ path \带\空格的用户插入警告消息,那么该代码最好放在哪里?

您可以先查看参数解析代码,然后在确定路径后添加检查。

在这样的补丁上是否存在明显的限制,可以让支持者共享这些限制,以消除访问者进行首次贡献时遇到的障碍?

他们大多可通过在这里寻找问题列表多年来就这个问题和其他问题提出的各种意见中找到,但首先,你需要拒绝路径时,他们将工作-这意味着要找出何处限制操作系统施加。 这些在系统之间差异很大。 Windows允许使用空格和长文件名,某些Unix系统允许使用空格,有些需要使用空格将路径引号,有些则具有非常短的长度限制(32个字符?),有些则更长,...很多限制没有得到很好的记录,并且很少贡献者可以使用足够的系统来测试所有可能性,以补充可用的文档。

拥护者是否对接受这样的补丁有一些历史异议?

不,除了“不要以为乍看之下就这么简单,也不要忽略我们必须支持的所有各种系统(有时相当晦涩)”。

如果有人确实想对此采取行动-并且他们应该意识到,这不是我个人建议的“第一稿”-那么他们应该首先阅读各种问题中的所有历史记录(某些从这个链接起来,其他人可能没有,一些可能在pip跟踪器上,甚至在distlib或setuptools跟踪器上),并在新的PR中总结了各种OS施加的约束。 提议作为说明“除非满足这些条件的文档修补程序”,否则virtualenv使用的shebang标头将无法按预期方式工作,因此virtualenv不支持在与指定条件不匹配的目录中创建环境。 PR可以包含代码更改以警告是否未满足记录的条件,或者可以作为将来的工作提出建议(根据我的回忆,要精确地对系统详细信息进行内省以了解适用的限制非常困难,请考虑“ Ubuntu带有补丁的内核” ...)。 就我个人而言,我会警告我,那就是只标记已知情况下可能会失败的警告,如果不确定则保持沉默。 但是,在此阶段使用纯文档补丁也可以。

然后,您需要从有权访问您所涵盖系统的人员那里获得对补丁程序的评论-如前所述,核心开发人员并不能真正在这里提供帮助,因为我们都不使用(例如)FreeBSD,OpenBSD或Solaris,要么 ...

您也可以只做部分工作,并创建添加(例如)OSX文档和警告的PR。 我不知道这是否可以停止对这个问题的抱怨(我不知道这种情况最常出现在什么系统上),但也许就足够了。 可能使用OSX的核心开发人员之一可以将其合并。

有帮助吗?

也许我听不懂,但是不能通过包含(例如) bin/pip来解决此问题

#!/bin/sh
"/my/long path/with spaces/pythonx.y" "/path/to/my project/with spaces/venv/bin/real-pip" "$@"

然后将当前的pip脚本移至real-pip ? 我不明白为什么我们必须直接使用shebang。

@ raxod502我假设您知道这在Windows上不起作用。 另外,我认为第二行需要的“正常”咒语比您给出的要复杂(尽管我个人不知道为什么)。 您可能可以通过网络搜索找到合适的方法。 使用您的方法,如果路径中包含"$字符,该怎么办?

假设您可以解决此类问题,那么我想下一步是您要提交PR(根据上面的评论),我们可以就此进行辩论。 您需要至少一名参与Unix的virtualenv核心提交者-作为Windows用户,我不愿意像我这样合并特定于Unix的PR。

@pfmoore
@ raxod502提出的解决方案也可以在带有.bat脚本文件afaik的Windows上工作?

@gst简短答案,不。 长的答案是http://paul-moores-notes.readthedocs.io/en/latest/wrappers.html已经有关于这一点,多年来许多讨论,每一次有人拿出比其他解决方案exe包装器,出现了问题。

在这种情况下,请记住Windows上不存在此问题。 因此,绝对没有理由在Windows环境中进行任何更改-任何更改都必须仅限于Unix。

谢谢你好答案:)

除了exe包装外,它还是有问题。

就个人而言,我可以忍受(如果需要)。

我更新了distlib以处理长路径和带空格的路径。 我没有直接使用Harald Nordgren的补丁程序(它有一些问题-例如没有测试),但是方法是相同的-使用'/ bin / sh'作为可执行文件。 pip / virtualenv维护者可能希望在本地销售distlib存储库的当前版本后进行测试。

pip的开发版本现在为distlib的较新版本提供了厂商,这意味着pip现在可以很好地处理目录名称中的空格。

据我了解,一旦制作了下一个pip版本和virtualenv版本,此问题将得到解决-创建的任何新virtualenv都将支持路径中的空格,以及pip安装的二进制文件(除非在某些奇怪的情况下,如setuptools '不是由pip直接安装的包装器)。

我刚刚开始使用gvfs在用户空间中挂载samba共享,并发现由于gvfs生成的挂载路径中的惩罚而使virtualenv / pip等崩溃了。

路径上没有空格,但是有很多其他东西可以使virtualenv / pip等跪倒在目录中

/run/user/1000/gvfs/smb-share:server=bolt,share=eng/projects/msp/mrfbus/land

据我所知,gvfs中目前没有任何选项可以防止在其生成的安装点的路径中出现标点符号。 我唯一的解决方法是永远不要在gvfs挂载上创建virtualenv,这似乎有点可悲

@pradyunsg是否有下一个pip版本的时间表? 最后一个是一年多以前的,似乎很愚蠢的等待这么长时间才能在virtualenv中显示此非常简单的修复程序。

嗨@ raxod502!

是的,我们希望尽快推出。 问题是我们在开发人员上缺少PEP 518的时间,这是我们想要做的。 可能刚好有一个没有PEP 518的点子10,但是同样,这取决于找到解决方案的时间。

看来此错误已由2018-04-14发布的distlib 0.2.6中,该于2017年10月与pip ,该PR4819首先出现在pip 10.0.0b2中。

潜在的修复似乎在distlib的commit 9285cca中。 正如vsajip在2017年5月28日在此处评论的那样,该方法遵循Harald Nordgren的想法:在简单情况下(操作系统不是Posix,或者路径足够短且没有空格)继续使用简单的shebang,但对于非简单情况则使用而是使用/bin/sh exec命令,该命令可以处理长路径或包含空格的路径。

我在Mac OS X 10.11.6上进行了快速测试,在很长的路径中创建了一个带有空格的虚拟环境,然后调用pip3 install ,它似乎可以正常工作。 我尚未完全测试此错误中描述的所有问题是否已在每个OS上修复。

使用Ubuntu 16.04.5 LTS将pip从9.0.1升级到18.1(它们切换到基于日历的版本)并将virtualenv从15.0.1升级到16.0.0后,问题似乎消失了:

sudo pip install --upgrade pip
sudo pip install --upgrade virtualenv

现在,所有pip命令都可以在virtualenvs中正常运行,它们的根路径中有空格。

正如@JLDH@gandie所确认的,此问题现已解决。 当virtualenv的根目录中有空格时,最新版本的pip和virtualenv可以一起正常工作。

结束了! 感谢您对基础修复@vsajip所做的工作!

旧票:但是为什么不

!/ usr / bin / env python吗?

@rirl ,我认为对已结束的问题发表评论不太可能引起您的想法关注。 该问题已得到解决。 如果您认为采用此解决方案的新虚拟机将通过做不同的事情得到改善,那么您正在提出新的更改。 考虑打开一个新的Issue,说出您认为应该进行的更改,并说明为什么该更改比新的virtualenv更好的理由。

此页面是否有帮助?
0 / 5 - 0 等级