использование альтернативного расположения / tmp с pyinstaller


У меня есть скрипт Python, который я затем запустил через pyinstaller2.0, чтобы сгенерировать его двоичный файл.

python pyinstaller -F /path/to/python/script

При запуске двоичного файла он по умолчанию использует папку /tmp для сохранения временных файлов и запуска программы установки. Это прекрасно работает на обычных серверах и VPS. Однако при попытке установки на сервере, где /tmp отключен (/tmp noexec), установка завершается неудачей.

Мои вопросы таковы:

  • как бы я включил другое временное местоположение, когда двоичный файл запускается? есть ли у pyinstaller такая возможность?
  • Если я напишу код для создания временного расположения и экспортирую его в путь внутри скрипта python, не будет ли он в любом случае пытаться использовать default /tmp для запуска двоичного файла python?
  • другой метод, который я придумал, состоял в том, чтобы написать сценарий оболочки в bash, который создает расположение temp, экспортирует его путь, затем вызывает двоичный файл python и после его запуска удаляет расположение temp из Пути и удаляет папку temp - но это похоже на окольный путь, чтобы сделать это. Есть ли лучшее решение?
3 4

3 ответа:

Решение, предложенное @devnull, действительно состояло в том, чтобы внести изменения в сценарий pyinstaller. В сценарии было жестко закодировано временное местоположение, поэтому я внес в него изменения. Итак, вот следующие шаги:

  • в папке pyinstaller найдите файл launch.c в папке /path/to/pyinstaller/sources/common
  • найдите функцию с именем int getTempPath(char *buff)
  • под ним удалите ссылки на static const char *envname[] (которые являются объявлением и одним циклом for внутри одной функции)
  • измените значения для static const char *dirname[] к тем значениям, которые вы хотите.

Функция, таким образом, выглядит так:

int getTempPath(char *buff)
{
        static const char *dirname[] = {
                "/usr/local/src/temp", "/usr/local/src", "/usr/src", 0
        };
        int i;
        char *p;
        for ( i=0; dirname[i]; i++ ) {
                strcpy(buff, dirname[i]);
                if (testTempPath(buff))
                        return 1;
        }
    return 0;
}

Перекомпилируйте pyinstaller sources, используя следующую команду:

python ./waf configure --no-lsb build install

Чтобы запустить это, сначала установите python-devel пакеты (yum install python-devel -y) иначе он выбрасывает и ошибка, что Python.h isn't found

Теперь, когда мы запускаем скрипт python через pyinstaller, используется новый temp local. Спасибо @devnull за то, что указал мне правильное направление.

@devnull был на правильном пути. Недостающая часть состоит в том, что эти переменные среды разрешаются при запуске двоичного файла установщика на целевой машине, а не при компиляции установщика на машине разработки.

Двухстрочный сценарий оболочки, который изменяет переменную среды TMPDIR (или % TEMP% в Windows) в место, откуда вы можете запустить код, а затем вызывает скомпилированный двоичный файл, должен выполнить эту работу.

Кстати, этот метод имеет то преимущество, что он также работает, если вы получаете pyInstaller сгенерированный двоичный файл от кого-то другого и не имеете доступа к исходному коду.

Как отметил @Darkerlvy в комментарии теперь есть опция командной строки --runtime-tmpdir PATH, которую вы можете передать pyinstaller. Нет необходимости изменять источник или устанавливать переменную env. Он был введен в pyinstaller 3.3