Как использовать виртуальное окружение Python с sudo?

Вопрос или проблема

Я пытаюсь создать окружение python, отдельное от системного (используя virtualenv), в директории, которая не находится в /home, потому что мне нужно использовать его для сборки другого ПО, которое должно быть доступно нескольким пользователям. Я могу создать и активировать virtualenv без проблем, но когда я sudo выполняю какую-то команду (например, для сборки или компиляции другого ПО), используется системный python (я могу понять это по доступным модулям).

Поскольку на Ubuntu использование root пользователя – не очень хорошая идея, есть ли способ заставить sudo использовать virtualenv? Или, возможно, это не правильный подход, и мне следует сделать совершенно новую установку python?

Я использую 64-битную версию Ubuntu 12.04 (и python 2.7).

Проблема, почти наверняка, в том, что когда вы запускаете sudo, переменные окружения virtualenv, псевдонимы, функции и т.д. не передаются.

Решение будет заключаться в том, чтобы явно запускать исполняемый файл Python виртуальной среды с sudo. Например, если ваш virtualenv это ./AwesomeProject, тогда вы можете выполнить sudo ./AwesomeProject/bin/python <script>, чтобы использовать скрипт с virtualenv с правами суперпользователя.

В зависимости от вашей конкретной задачи это может или не может решить вашу проблему, но это еще не было упомянуто здесь. Скажем, вы хотите запустить Python скрипт, который был установлен в вашей виртуальной среде, и вам нужно setuid(0), т.е. вы хотите запустить его как суперпользователь. Скажем, ваш скрипт называется myscript.py, тогда вы можете сделать это так:

(.venv) $ sudo -E env PATH="$PATH" ./myscript.py

Объяснение

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

sudo -E сообщит sudo, что при запуске процесса ему нужно скопировать переменные окружения из вашей текущей оболочки. Поэтому, если у вас есть какие-либо дополнительные переменные, определенные в скрипте .venv/bin/activate, они должны остаться, пока вы root.

env PATH=$PATH при использовании sudo -E не все переменные окружения сохраняются, в частности, и что самое важное, PATH может быть удален. Конкретные особенности этого поведения будут зависеть от вашего файла sudoers. Однако это обойдет все, что написано в файле sudoers, поскольку он явно скопирует PATH в переменную окружения, которую sudo создает для нового процесса. Это важно, потому что когда ваша система разрешает комментарий shebang в вашем myscript.py, она будет искать в переменной PATH, и первый каталог, соответствующий требованиям для интерпретатора, будет использован. venv, с другой стороны, настраивает окружение оболочки таким образом, что каталог, содержащий символическую ссылку на выбранный интерпретатор Python, появляется первым, тем самым заставляя систему находить нужный Python перед любыми другими версиями Python в системном пути.

Иногда вам нужно обновить $PATH, потому что скрипт запускает другие программы. Например, pypi-install нуждается в py2dsc-deb в PATH. Эта команда работает: sudo sh -c ". venv/bin/activate ; pypi-install $PACKAGE"

Я только что наткнулся на это и для других, кто может столкнуться с такой же проблемой, Кен прав, что переменные окружения не были переданы. Решение, которое я использовал, заключалось в добавлении следующих строк в мой скрипт. Это имеет дополнительное преимущество в том, что всегда загружает виртуальное окружение напрямую из скрипта. (Это означает, что вы можете использовать скрипт с crontab или launchd без каких-либо других обходных путей.)

base_dir = os.path.dirname(os.path.abspath(__file__))
activate_this = os.path.join(base_dir, 'venv/bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))

Больше информации здесь: https://virtualenv.pypa.io/en/latest/userguide.html#using-virtualenv-without-bin-python

Я хотел бы добавить свой ответ, потому что я только что столкнулся с такой же проблемой. Но я создал shell-скрипт для репозитория, и поэтому не хотел использовать жестко закодированный путь. Вот что я делаю сейчас:

  1. Войдите в ваше venv:
    source /path/to/your/venv/bin/activate
  2. Получите путь к бинарному файлу python3 виртуальной среды без sudo:
    PYTHON3_VENV_PATH=$(which python3)
  3. Теперь вы можете запустить свой скрипт с sudo и бинарным файлом python3:
    sudo $PYTHON3_VENV_PATH path/to/your/script.py

Ответ или решение

Использование виртуального окружения Python вместе с командой sudo может представлять собой некоторые сложности, особенно когда вы хотите, чтобы ваши скрипты и модули из виртуального окружения были доступны с правами суперпользователя. В этой статье я объясню, как правильно использовать виртуальные окружения с sudo, чтобы избежать проблем с доступом к системным модулям Python.

Введение в виртуальные окружения Python

Виртуальные окружения (virtualenv) позволяют создавать изолированные пространства для ваших проектов Python. Это особенно полезно для управления зависимостями различных проектов, предотвращая конфликты между библиотеками. Однако, когда дело доходит до использования sudo, виртуальные окружения не всегда работают так, как ожидается.

Проблема с sudo и виртуальными окружениями

Когда вы запускаете команду с sudo, текущий контекст окружения не сохраняется. Это значит, что все переменные окружения, настроенные при активации виртуального окружения, не будут доступны, и будет использоваться системная версия Python. Это приводит к тому, что доступные модули и библиотеки могут отличаться от тех, которые находятся в вашем виртуальном окружении.

Решения для использования sudo с виртуальными окружениями

1. Запуск напрямую через интерпретатор виртуального окружения

Наиболее простым и эффективным способом использования виртуального окружения с sudo является запуск Python интерпретатора из вашего виртуального окружения с правами суперпользователя. Пример команды:

sudo /path/to/your/venv/bin/python /path/to/your/script.py

Это гарантирует, что будет использоваться Python из вашего виртуального окружения, а не системный.

2. Сохранение переменных окружения с помощью sudo -E

Команда sudo с параметром -E позволяет сохранить переменные окружения, установленные в текущем сеансе. Например:

sudo -E env PATH="$PATH" ./myscript.py

При этом будет сохранен ваш текущий $PATH, что позволит вашему скрипту обнаружить зависимости из виртуального окружения.

3. Использование оболочки для активации окружения

Если ваш скрипт требует сложной настройки окружения, вы можете использовать оболочку для активации виртуального окружения. Пример команды:

sudo sh -c ". /path/to/your/venv/bin/activate; python your_script.py"

4. Скрипт для автоматизации активации виртуального окружения

Если вы хотите, чтобы ваш скрипт всегда использовал правильное виртуальное окружение, вы можете добавить автозагрузку активации в код:

import os
import sys

base_dir = os.path.dirname(os.path.abspath(__file__))
activate_this = os.path.join(base_dir, 'venv/bin/activate_this.py')
exec(open(activate_this).read(), dict(__file__=activate_this))

Таким образом, ваш скрипт будет автоматически загружать виртуальное окружение независимо от того, как он запускается.

5. Гибкое получение пути к Python виртуального окружения

Если вам нужно программное решение, вы можете динамически получить путь к Python интерпретатору в вашем виртуальном окружении и использовать его с sudo:

source /path/to/your/venv/bin/activate
PYTHON3_VENV_PATH=$(which python3)
sudo $PYTHON3_VENV_PATH /path/to/your/script.py

Заключение

Использование виртуальных окружений Python вместе с sudo может быть непростой задачей, но с правильным подходом и пониманием особенностей работы командной строки вы сможете успешно управлять своими зависимостями и запускать скрипты с необходимыми правами. Будьте осторожны с правами суперпользователя, чтобы избежать повреждения системы или проблем с безопасность. Если у вас есть дополнительные вопросы или вам нужны разъяснения по конкретным моментам, не стесняйтесь задавать их!

Оцените материал
Добавить комментарий

Капча загружается...