Python 2.3 distutils会将shebang覆盖为/usr/bin/python,而不是/usr/bin/env python。

3
我有一个安装在共享开发系统上的软件包。我希望该软件包引入的脚本只对我的用户(或任何其他请求者)可用。为了安装该软件包,我正在使用以下命令从软件包目录中执行: python setup.py install --home=~
到目前为止,这样做的效果都很好。它安装了我的模块并将脚本放在/home/$(whoami)/bin目录中。
然而,它替换了脚本文件中的shebang。因此,不再是友好的#!/usr/bin/env python,而是替换为#!/usr/bin/python。
现在,由于我的软件包仅安装给当前用户,因此无法查看软件包内部的模块进行导入。
因此,由于我的脚本从软件包内部导入函数,因此从命令行运行它们会导致导入错误。
使用交互式Python解释器可以让我使用与我想要运行的脚本中导入行完全相同的文本导入文件。
有人知道如何解决这个问题吗?
P.S. 对于可预见的未来,我无法控制此设置中的Python版本。它是2.3.4。
1个回答

0
编辑:我忘了提到 --executable 选项。我不知道2.3版本是否有这个选项,但在2.7版本中它可以用来覆盖哈希bangs的重写,使用当前解释器的内容。在尝试其他方法之前,请先试试这个。

如果 --executable 开关不起作用,您应该能够按照您自己的方式编写 setup.py 文件。setup.py 的关键是要调用 distutils.core.setup()。如果在调用 setup() 时 distutils 在做一些奇怪的事情,请在 setup.py 的例程后面添加一个修正:

from distutils.core import setup
import os
setup(name='foo', version='1.0', py_modules=['spam', 'eggs'])
fix_hashbang(script_list):
    sed = "sed -i 's/#! \/usr\/bin\/python/#! \/usr\/bin\/env python/'"
    cmd = ' '.join([sed, ' '.join(script_list)])
    os.system(cmd)
fix_hashbang(list_of_scripts)

“list of scripts”是一个包含要更新的脚本路径的字符串列表。这个解决方案有点奇怪。我知道在2.7版本中--executable可以工作,而且在2.3版本中肯定有类似的东西,即使没有完全相同的开关。

非常好。我会去查一下,但是你知道如何只将这种后期处理应用于脚本文件吗? - undefined
我根据我理解的你所说的“仅限脚本文件”更新了答案。由于在我看来这是最直接的方法,我选择在主机系统上使用sed(而不是使用Python的fileinput模块或倒出行列表、更改一行,然后重新写入整个文件等)。实际上,由于是使用sed,它只会更改精确匹配的错误hashbang,因此可以安全地遍历所有安装文件。 - undefined
--executable选项绝对不会起作用。它在2.3版本中不可用...我在Python文档中看到了它,感到兴奋,直到发现它不起作用。你知道,在这种情况下使用sed是完全过度杀伤力的,因为shebang行只能出现在文件的第一行上。而且似乎该方法只会修复已经在包中的脚本的shebang行,而不是安装它们的脚本。还是非常感谢你的帮助。 - undefined
我觉得你没有理解这里发生的事情。setup()函数实际上完成了复制和哈希重写的工作。一旦这行代码执行完毕,安装就完成了,文件也被放置在你的文件系统中,永久保存。之后的任何操作都由你决定。所以,如果你将fix_hashbang()函数传入一个包含有损哈希的脚本文件路径列表,它们将在此时修复,而不是在原始软件包中修复。无论如何,考虑到其他选择,我认为使用sed命令并不过度。 - undefined
不要傲慢,这样做对讨论没有任何帮助。以编程方式修复列表中的每个脚本并非易事。由于--home参数作为setup.py的一个参数传递,我首先需要自己解析它。然后使用它来构建每个脚本的路径。到那时,即使尝试在setup复制脚本之后自己操作它们也毫无意义;我可以直接按原样移动它们并省略脚本参数。无论如何,前进的道路都没有一个干净、优雅的方法,而在Python脚本中使用命令行sed也不是一个好选择。 - undefined
显示剩余2条评论

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