Virtualenv: Превышена длина Shebang в исполняемом файле pip

Созданный на 25 апр. 2014  ·  16Комментарии  ·  Источник: pypa/virtualenv

Когда создается новый virtualenv, в него устанавливается ряд вещей. Одна из таких вещей - установщик пакетов Python, pip.

В Linux исполняемый файл pip представляет собой сценарий оболочки. Вверху этого сценария оболочки pip находится строка shebang (#!), Которая указывает интерпретатор python в файле virtualenv. Эта строка содержит абсолютный путь к интерпретатору python.

Если абсолютный путь к интерпретатору python в virtualenv очень длинный (глубоко вложенные и / или большие имена путей), он может превышать максимальную длину, разрешенную для строки shebang.

Максимальная длина строки shebang ограничена в ядре параметром BINPRM_BUF_SIZE, установленным в /usr/include/linux/binfmts.h. На машинах Linux, на которые я смотрел, этот предел установлен на 128.

Итак, когда путь к месту создания python virtualenv становится слишком длинным, использование этого протокола virtualenv не будет работать. Произойдет сбой с ошибкой: «плохой интерпретатор: нет такого файла или каталога».

Обход этой проблемы - не запускать pip напрямую, а запускать интерпретатор python virtualenv и передавать скрипт pip на python в качестве источника для выполнения.

Самый полезный комментарий

Если кого-то это смущает:

Обход этой проблемы - не запускать pip напрямую, а запускать интерпретатор python virtualenv и передавать скрипт pip на python в качестве источника для выполнения.

Это означает, что вместо pip install -r requirements.txt do python -m pip install -r requirements.txt

Все 16 Комментарий

У меня тоже возникла эта проблема.

Я тоже.

Спасибо за обходной путь!

Обратите внимание, что сценарии оболочки на самом деле создаются с помощью setuptools (если вы устанавливаете из sdist) или distlib (если вы устанавливаете из wheel). Поэтому любое исправление этой проблемы действительно следует запрашивать у этих проектов.

Но если это ограничение ОС, может быть, это просто _не_ жизнеспособное исправление? Я, кажется, помню, что одно время Perl использовал волшебное заклинание для выполнения скриптов (немного погуглил ...) Да, что-то вроде этого (переведено на Python)

#!/bin/sh
eval 'exec /the/long/interpreter/path/to/python $0 ${1+"$@"}'

Вам понадобятся дополнительные вещи, чтобы Python не пытался выполнить строку eval-exec, но это может сработать.

Если бы кто-то хотел предложить что-то подобное в качестве запроса функции для setuptools и distlib, это было бы здорово.

Итак, когда путь к месту создания python virtualenv становится слишком длинным, использование этого протокола virtualenv не будет работать.

Было бы _действительно_ приятно, если бы при запуске virtualenv в системе, в которой возникает эта проблема, команда выдала бы предупреждение (или даже ошибку), что нахождение в каталоге с таким длинным именем пути по существу не поддерживается значения по умолчанию на данный момент.

Я тоже попадаю в это. Это конкретная проблема для меня, так как я запускаю pip из сборок Jenkins, которые имеют очень длинные пути к pwd. Интересно, что у меня есть несколько идентично построенных ведомых устройств сборки (у всех BINPRM_BUF_SIZE установлено значение 128 и те же версии pip, python и virtualenv), и я испытываю это на некоторых из них, но не на других, даже с различной длиной пути.

Мне нравится предложение @b-long; если virtualenv собирается создать оболочку, которая не работает в текущей системе, она должна, по крайней мере, выдать пользователю предупреждение, если не привести к полной ошибке.

Непонятно, как virtualenv мог обнаружить эту ситуацию. Мы не можем точно использовать значение из заголовка C, и я не знаю, как мы обнаружим, что находимся в системе с этим ограничением (в Windows его нет, а в OSX?)

Я склонен закрыть эту проблему как ограничение ОС, а не проблему virtualenv.

Чего стоит, некоторые мысли ...

  1. может ctypes это сделать?
  2. Как насчет чего-то столь же простого, как:
# on Linux, BINPRM_BUF_SIZE == 128, giving us a maximum shebang length of 127
# 2 bytes for #!, 11 bytes for '/bin/python' leaves us with 114
if sys.platform() == 'Linux' and len(home_dir) > 114:
    log.warn("bin/activate may not work your system, as the length of the shebang line will exceed 128 characters")
  1. Понятия не имею, извините.
  2. Я пользователь Windows, поэтому у меня нет мнения. Если вы думаете, что это разумно, я предлагаю поднять PR и посмотреть, что думают люди, занимающиеся Linux ...

Я уверен, что другие пользователи также оценят предложенное мной изменение. Можем ли мы оставить это открытым для комментариев и для создания пиара? Спасибо @jantman и @pfmoore : smile:

BINPRM_BUF_SIZE определяется в заголовке ядра и, похоже, используется лишь небольшой горсткой функций ядра. Я не верю, что есть какой-либо способ программно обнаружить это (за исключением чтения заголовков, что практически невозможно).

Это , как говорится, я думаю , что это разумно предположить , что это не будет меняться в ближайшее время (есть краткий обзор максимальная хижину длины здесь ). Текущая длина также четко указана в разделе «Примечания» на странице руководства

Я бы предположил, что все POSIX-совместимые операционные системы имеют какое-то ограничение, хотя кажется, что некоторые из них, особенно варианты BSD, могут иметь ограничения до 8000 символов.

Хотя кажется, что было бы разумным решением просто жестко закодировать что-то столь же наивное, как мое вышеупомянутое предложение (если платформа Linux и строка длиннее 127 символов), мне это кажется слишком грубым, конкретным и негибким.

Я все еще думаю о том, как бы программно протестировать это таким образом, чтобы не добавить слишком много накладных расходов к virtualenv (конечно, нам нужно будет проверить это только во время создания venv, поэтому я Я предполагаю, что некоторые накладные расходы могут быть приемлемыми).

У меня есть простой проверочный код, чтобы проверить, является ли данный путь приемлемой длиной she-bang, но он довольно уродлив, поскольку он записывает файл на диск, а затем выполняет файл для захвата вывода. Пример и результат здесь: https://gist.github.com/jantman/ba39f98936643bc948bd

Я собираюсь закончить это вечером, но я постараюсь вернуться к этому. Я, безусловно, был бы признателен за вклад любых других пользователей Linux или пользователей других ОС, которые могут подтвердить, есть ли у них аналогичный лимит.

Вместо того, чтобы пытаться сделать что-то сложное, например, сделать предположения о пределе, почему бы просто не создать функциональный тестовый сценарий bash? Если python вызывается правильно, то все отлично, в противном случае - нет.

Повторить:

  1. Пожалуйста, отправьте PR в setuptools и distlib если вы хотите, чтобы это было исправлено - код не в virtualenv или pip.
  2. Чтобы код был приемлемым, он должен работать на всех поддерживаемых платформах, включая OSX, BSD, ... а не только на Linux (конечно, допустимы условия для конкретных платформ, если нет другого пути)

Закрытие этой проблемы, поскольку это не проблема virtualenv (вы можете получить тот же эффект, установив полный интерпретатор Python на длинное имя каталога).

Мы только что затронули эту проблему.

Почему бы не использовать питон из PATH? virtualenv уже добавляет его в каталог bin.

#!/usr/bin/env python

virtualenv уже добавляет его в каталог bin

Только если вы активируете файл virtualenv. Virtualenv поддерживает использование без активации.

Если кого-то это смущает:

Обход этой проблемы - не запускать pip напрямую, а запускать интерпретатор python virtualenv и передавать скрипт pip на python в качестве источника для выполнения.

Это означает, что вместо pip install -r requirements.txt do python -m pip install -r requirements.txt

Была ли эта страница полезной?
0 / 5 - 0 рейтинги