Не трогай мой член
-
20-09-2019 - |
Вопрос
Одна вещь, которую я ненавижу диституты (Наверное он злой, кто это делает) заключается в том, что он меняет линию Шебанга.Другими словами, более рациональные и средовые вары решили, что Священное Писание
#!/usr/bin/env python
волшебным образом превращается в
#!/whatever/absolute/path/is/my/python
Это также видно с помощью grok:Я использовал grokproject в виртуальной среде, чтобы запустить свой проект, но теперь я больше не могу перемещать каталог разработки, потому что он помещает абсолютные пути в директиву shebang.
Причина, по которой я спрашиваю об этом, двоякая.
- Я хочу переместить его, потому что я начал разработку в одном каталоге (Эксперименты), а теперь хочу переместить его в правильный путь, но не смог этого сделать.Поэтому я создал новый virtualenv и grokproject и скопировал свои файлы.Это решает проблему, но оставляет мое любопытство в поисках более рационального решения неудовлетворенным.В частности, если бы ссылка на интерпретатор python virtualenv была относительной, проблемы вообще не было бы.Вы знаете структуру virtualenv и можете легко обратиться к python virtualenv.
- Вторая причина заключается в том, что я хотел бы иметь возможность перенести виртуальную среду на другой компьютер и без проблем запустить ее там.Это невозможно, если у вас жестко запрограммированы пути.
Решение
Конечно, вы можете перемещать каталог разработки.Distutils меняет пути к Python, который вы должны использовать при его запуске.Это происходит в Grok Run, когда вы запускаете сборку.Переместите и повторно запустите загрузку и сборку.Сделанный!
Distutils меняет путь к Python, который вы используете для запуска distutils.Если этого не произойдет, вы можете в конечном итоге установить библиотеку в одной версии Python, но при попытке запустить сценарий произойдет сбой, поскольку он будет работать с другой версией Python, в которой нет библиотеки.
Это не безумие, на самом деле это единственный разумный способ сделать это.
Обновлять:Если вы знаете, что делаете, вы можете сделать это:
/path/to/install/python setup.py build -e "/the/path/you/want/python" install
Однако сначала убедитесь, что вы очистили каталог сборки.:)
Другие советы
Distutils автоматически заменит shebang расположением двоичного файла Python, который использовался для выполнения setup.py.Чтобы переопределить это поведение, у вас есть два варианта:
Опция 1:Вручную
Вы можете передать флаг --executable=/путь/к/моему/python в setup.py.Аргументы принимаются.
Пример:
% python setup.py build --executable=/opt/local/bin/python -d
Вариант 2:Автоматически
Другой вариант — добавить строку в файл setup.cfg.Если вы не используете setup.cfg, создайте его в том же каталоге, что и setup.py.Setup.py ищет это при запуске.Любые указанные здесь параметры по-прежнему можно переопределить с помощью флагов в командной строке.
% cat setup.cfg
[build]
executable = /opt/local/bin/python -d
У меня нет решения вашей проблемы, но я вижу некоторое обоснование текущего поведения диституты.
#!/usr/bin/env python
выполняет системную версию Python по умолчанию.Это нормально, если ваш код совместим с указанной версией.Когда версия по умолчанию обновляется (скажем, с 2.5 до 3), ваш код или другой код Python, который ссылается на /usr/bin/env
может перестать работать, даже если старая версия Python все еще установлена.По этой причине имеет смысл «жестко запрограммировать» путь к соответствующему интерпретатору Python.
Редактировать: вы правы, утверждая, что указание python2.4
или аналогичный решает эту проблему.
Редактировать 2: все не так однозначно, когда присутствует несколько установок одной и той же версии Python, поскольку Нед Дейли указывает в комментариях ниже.
В одной из последних версий диституты, есть флаг --no-autoreq которые сработали для меня:
--no-autoreq do not automatically calculate dependencies
В моем случае я создавал файлы RPM с исполняемым файлом python2.4 на сервере с установками как 2.4, так и 2.6.bdist просто оставил шебанги такими, какие они есть, после запуска:
python setup.py bdist_rpm --no-autoreq
В случае, если вы обрабатываете спецификация файлы, вы можете использовать решение, описанное в https://stackoverflow.com/a/7423994/722997, добавив:
AutoReq: no
была такая же проблема.пытался найти способ вообще предотвратить прикосновения по умолчанию.вот решение.по сути, мы переопределяем стандартную процедуру копирования скриптов (build_scripts).
в setup.py добавить
from distutils.command.build_scripts import build_scripts
# don't touch my shebang
class BSCommand (build_scripts):
def run(self):
"""
Copy, chmod each script listed in 'self.scripts'
essentially this is the stripped
distutils.command.build_scripts.copy_scripts()
routine
"""
from stat import ST_MODE
from distutils.dep_util import newer
from distutils import log
import os
self.mkpath(self.build_dir)
outfiles = []
for script in self.scripts:
outfile = os.path.join(self.build_dir, os.path.basename(script))
outfiles.append(outfile)
if not self.force and not newer(script, outfile):
log.debug("not copying %s (up-to-date)", script)
continue
log.info("copying and NOT adjusting %s -> %s", script,
self.build_dir)
self.copy_file(script, outfile)
if os.name == 'posix':
for file in outfiles:
if self.dry_run:
log.info("changing mode of %s", file)
else:
oldmode = os.stat(file)[ST_MODE] & 0o7777
newmode = (oldmode | 0o555) & 0o7777
if newmode != oldmode:
log.info("changing mode of %s from %o to %o",
file, oldmode, newmode)
os.chmod(file, newmode)
setup(name="name",
version=version_string,
description="desc",
...
test_suite='testing',
cmdclass={'build_scripts': BSCommand},
)
..ede/duply.net