Приветствую всех, кто каким-то чудом нашел этот блог. Формат данного блога свободный и в нем я стараюсь делиться различными полезностями, размышлениями о различных событиях, своим творчеством.

Меняем версии python самыми примитивными методами

python

“Levitating Royal Python” by susie2778 is licensed under CC BY-NC 2.0, modified by SEVA77

Это вроде уже вторая моя статья в стиле “от нуба для нубов”. Что-то похожее было про макросы в си. В статье расскажу, как в линуксе легко менять версии python на необходимые как глобально, так и в рамках одной терминальной сессии без использования специальных утилит.

По крайней мере это сейчас легко, а когда-то давно, помню, были некоторые разбирательства, связанные с прописанными в скриптах запуска python через env. Имею в виду первую строчку скрипта на python:

#!/usr/bin/env python

Видел и другие варианты, но редко. В основном много кто приписывает запуск питона через env. И в моем случае сначала задачка была поменять python с третьей версии на вторую, ибо в сборочных скриптах для chromium под запуском python подразумевается именно вторая его версия, а когда нужна именно третья версия, прописывается запуск python3. Ну а позже была потребность переключать конкретно минорные версии питона (с 3.11 на 3.10 например), но обо всем по порядку.

Итак.

Меняем версии глобально

Только в специфических случаях! Не рекомендуется для обычного использования.

Прописывание алиаса на команду python не помогает, после чего нашёл специальную утилиту pyenv, которая меняет версии python и … она тоже почему-то не помогла. Позже скажу почему.

Ну не помогла и не помогла, ищем дальше. В итоге я в дальнейшем нашел размытое пояснение, мол ну вот такая особенность запуска питона через env, что берется глобально установленная версия питона потому если хотим поменять версии питона с третьей на вторую, то нужно в папке /usr/bin/ удалить файл-ссылку python:

sudo rm /usr/bin/python

ссылающуюся на третий питон и на ее месте создать такую же ссылку, но уже на второй питон:

sudo ln -s /usr/bin/python2 /usr/bin/python

Наверное для маленьких на всякий случай следует пояснить, что когда вы прописываете всякие разные команды в терминал, система их ищет в виде исполняемых файлов или ссылок на исполняемые файлы с таким же названием по путям, прописанным в переменной PATH, в том числе и в нашей основной папке /usr/bin/. Ну и после установки как третьего, так и второго питона в этой папке появляются аж 5 файлов, его запускающих: python3.11 (исполняемый), python2.7 (исполняемый), python3 (ссылка на python3.11), python2 (ссылка на python2.7), python (ссылка на python3, которую мы как раз и меняем).

Естественно может оказаться так, что в PATH может быть путь приоритетнее (первее) /usr/bin/, по которому тоже находится python, а потому запускаться будет именно он и не лишним будет на всякий узнать этот путь командой … ну например:

type python

и менять версии уже по этому пути.

По итогу мы можем просто объединить команды удаления и создания ссылки в одну и для переключения версии питон на вторую, просто вставляем эту команду:

sudo rm /usr/bin/python && sudo ln -s /usr/bin/python2 /usr/bin/python

а чтоб обратно вернуть третий питон, вставляем эту:

sudo rm /usr/bin/python && sudo ln -s /usr/bin/python3 /usr/bin/python

Вот вам и удобное глобальное переключение между питоном 2 и питоном 3 как основным. Естественно, когда речь идет об изменении их минорных версий (число после двойки или тройки) на таком же глобальном уровне, то просто устанавливают необходимую версию вместо уже существующей.

Последствия глобального изменения версий python могут быть достаточно ощутимыми, ибо помимо какого-то одного поделия, которое как раз и нужно заставлять работать под определенной версией питона, есть еще и различные другие программы и фоновые процессы, которые используют эту же версию и могут просто-напросто перестать работать.

Меня, например, долгое время устраивало глобальное переключение питона с третьего на второй и наоборот при необходимости, пока не увидел, что оказывается вместе с таким переключением перестает работать фаервол ufw. А потом, с выходом питона версии 3.11, вдруг перестала компилироваться определенная необходимая мне версия хромиума, а при откате до 3.10 перестали запускаться новые версии необходимых мне программ.

В таких случаях понимаешь, что необходимо заставить работать старые скрипты под старыми версиями питона, установленными где-то отдельно. Ну т.е. наконец вникнуть в подробности запуска python через env.

Меняем версии локально

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

Как писал выше, у меня возникла потребность иметь не только python2 как основной, но и более старую версию python3. Естественно нужно было уже вникать в приколы запуска через env, что из себя этот env представляет и что можно сделать.

Из того, что я понял, утилита env – это базовая база линукса, о которой я как более менее продвинутый прошареный давний его пользователь, какого-то хрена не знал. Технически представляет собой набор переменных окружения. Именно эта штука отвечает за определение таких переменных окружения, как USER, PATH, HOME, PWD и т.д. именно для отдельной сессии.

Прикол запуска через env в том, что осуществляется поиск запрашиваемой программы исключительно по путям, прописанным в переменной PATH и она только от туда и запустится. Ни о каких фокусах с алиасами тут и речи быть не может. Используют такой метод запуска в основном там, где требуется прописывать полный путь к исполняемому файлу.

В то же время env позволяет задавать новые переменные и модифицировать уже существующие. Создание новой переменной в консоли и не только выглядит достаточно примитивно:

TEST_VAR='Hello World!'

И ровно то же самое, когда нам надо модифицировать переменную PATH для запуска конкретной версии python.

Но сначала нам надо куда-то и как-то устанавливать эти версии python. Можно вручную их скачивать с официального сайта и компилировать в определенную, удобную для вас папку, а можно воспользоваться той же утилитой pyenv, которая у меня как раз не сработала как переключатель версий python, но вполне хорошо работает, как сборщик и установщик отдельных ее версий. Допустим нам нужны python 2.7.18 и python 3.10.13. Соответственно для сборки и установки вводим следующие команды:

pyenv install -v 2.7.18
pyenv install -v 3.10.13

Полученные уже собранные версии python находятся в вашей домашней директории по пути ~/.pyenv/versions/. Можно посмотреть список доступных для сборки и установки версий python командой

pyenv install --list | grep " 3.10"

Выдаст все значения списка доступных версий, содержащих в себе “ 3.10”.

После установки добавляем в переменную PATH, именно В ЕЁ НАЧАЛО, пути, по которым находятся исполняемые файлы наших python версий, но при этом, чтоб самая главная версия python была первее (то, чем должен являться файл python по команде python -V, у меня он должен быть именно второй версии).

PATH=$HOME/.pyenv/versions/2.7.18/bin/:$HOME/.pyenv/versions/3.10.13/bin/:$PATH

Если необходимо, чтоб эта переменная окружения распространялась и на дочерние процессы, то модифицируем ее через export:

export PATH=$HOME/.pyenv/versions/2.7.18/bin/:$HOME/.pyenv/versions/3.10.13/bin/:$PATH

Готово.

Теперь для запуска скриптов из терминальной сессии, в которой мы модифицировали PATH, скрипты будут запущены конкретными, необходимыми нам версиями python.

Как позже оказалось, надо было заморочиться с настройкой pyenv под конкретную оболочку, чтоб он также срабатывал, как переключатель версий и по сути делал то же самое, что я описывал выше: модификацию PATH. Однако в нашем случае у нас есть возможность выбирать конкретные версии и для python2, и для python3, а не что-то одно.

Я уже говорил, что данное изменение версий касается не только терминальной сессии. Естественно так как мы просто модифицируем переменную окружения, то такое вполне себе легко сработает для фонового процесса в systemd через его конфиг и для установки версий python в терминале по умолчанию через .bashrc, .zshrc или др. файл настроек в зависимости от выбранной вами оболочки.

Стоит также отметить, что с отдельной версией python идет отдельная версия pip, которая отдельно от всей системы установит разные необходимые зависимости в рамках этой отдельной версии python, что очень даже удобно. Не буду вдаваться в подробности, просто скажу, что даже при потребности в одной и той же версии python, но разных версиях зависимостей вполне легко выкручиваться.

Выводы

Их особо не будет. Просто скажу, что вариант с глобальной версией подойдет для настройки какого-нибудь докер образа, либо заточенного под что-то специфическое устройства и пр., в то время, как вариант с изменением версий локально может подойти чуть ли не для чего угодно.

А еще скорее всего это все работает только при прописанном запуске через env, ибо я также видел скрипты, где в первой строчке скрипта прописывали полный путь к питону (#!/usr/bin/python), что неплохо было бы отслеживать и исправлять при необходимости.

За незнание утилиты env особо не огрызайтесь: я со скриптами и с этой утилитой особо не работаю. Как я и написал, это статья от нуба для по сути таких же нубов во всей этой хрени.

 29.10.2023