Удивительно, на на хабре до сих пор нет поста о такой, весьма интересной, замене шеллу как xonsh (github), с моей точки зрения синтаксис всяких shell'ов ужасен и не вижу никаких оснований сохранять его в 21 веке, а Python, в свою очередь, обладает прекрасным синтаксисом и массой других преимуществ, поэтому, на мой взгляд, он и должен быть языком автоматизации по умолчанию, чего и пытаеся достичь xonsh.
Какое-то время использую xonsh, поэтому думаю, что могу рассказать о нём достаточно для того, чтобы начать пользоваться.
Оговорки:
- xonsh это только про Python 3, но это норма.
- xonsh ещё не релизнулся (версия 0.8.3 на момент написания), видимо по мнению разработчиков ещё не все желаемые фичи реализованы, но по моим ощущениям всё работает (если разобраться с отличиями, о чём ниже).
Основная особенность xonsh в том, что он "магически" угадывает что вы ввели — команду питона или шелла, и это работает вполне хорошо.
Вставлять питонные код в команды шелла можно с помощью собаки.
Не буду подробно останавливаться, на том, какие есть возможности в xonsh, это понятно и наглядно описано в документации и всяких статьях, с моей точки зрения достаточно уже того, что вы можете получить нормальный синтаксис циклов в шелле:
worldmind@x ~ $ for i in range(3):
............... echo $SHELL Поэтому я постараюсь сосредоточиться на том, что не описано или описано плохо.
Установка
Я буду описывать установку (для Debian/Ubuntu) не требующую права суперпользователя, хотя я только недавно перешёл на такую схему, раньше я ставил в системные папки, прописывал его в /etc/shells и менял шелл командой chsh, но на первый взгляд всё работает также и при новом способе и он мне кажется более правильным, не хочется засорять систему пакетами не из репозиториев, но тут каждый решает для себя сам.
Ставим pip если ещё не:
sudo apt-get install python3-pipСтавим xonsh (без sudo), я привожу команду которая устанавливает все опциональные зависимости, чтобы получить все плюшки задуманные авторами, если кто-то хочет минимальную установку, то можно удалить квадратные скобки с содержимым:
pip3 install --user xonsh[ptk,pygments,proctitle,linux]Скорее всего у вас уже, где-нибудь в .profile в PATH добавляются пути к локальной папке с бинарниками $HOME/.local/bin, но они добавляются только при их наличии, поэтому нужно перезапустить терминал, чтобы этот код отработал и бинарник xonsh можно было запустить и посмотреть.
Обновление стандартно:
pip3 install --user xonsh --upgradevenv
Ставим venv если хотим пользоваться соответствующим функционалом (см. далее про vox):
sudo apt-get install python3-venvВсякие venv заточены под конкретные шеллы, поэтому xonsh предлагает свою обёртку называемую vox, но для комфортного использования стоит устанавливать расширение avox:
pip3 install --user xontrib-avoxУстановка pyenv
Если есть необходимость в виртуальных окружениях с произвольной версией питона, то нужно склонировать pyenv предварительно установив зависимости для сборки питона:
git clone https://github.com/pyenv/pyenv.git ~/.pyenvДалее в примере конфига можно узреть установку пары переменных окружения для использования pyenv.
Запуск
Теперь у нас всё установлено и осталось сделать xonsh шеллом, для того, чтобы не менять ничего вне юзерской папки я использую следующий код (по мотивам SO) для баша (если у вас другой шелл, то вы знаете что делать, но не используйте .profile т.к. xonsh его тоже читает) добавленный в .bashrc:
# set default shell without editing /etc/shells
if [ "${XONSH_VERSION:-unset}" = "unset" ] ; then
export SHELL=$HOME/.local/bin/xonsh
exec $HOME/.local/bin/xonsh -l
fiПерезапускаем шелл и, если всё прошло удачно, вы уже в xonsh т.е. по сути в питон консоли и можете например производить вычисления прямо в командной строке, например узнать сколько будет 2+2.
Настройка
Прежде чем начать пользоваться, стоит создать конфигурационный файл .xonshrc:
aliases['g'] = 'git'
import os
local_bin = '{}/.local/bin'.format($HOME)
if os.path.isdir(local_bin):
$PATH.append(local_bin)
$PYENV_ROOT = '%s/.pyenv' % $HOME
$PATH.insert(0, '%s/bin' % $PYENV_ROOT)
xontrib load vox
$PROJECT_DIRS = ["~/projects"]
xontrib load avoxПерезапускам шелл для применения новых настроек.
Стоит обратить внимание на человеческую модель данных — алиасы это словарь, пути это список, вроде очевидно, но почему-то не всегда оно так.
Также, мы в конфиге импортировали модуль os это значит что он уже будет доступен в нашем шелле, таким образом можно наимпортить нужных модулей и получить своё, удобное окружение.
Начало приведённого файла больше для демонстрации возможностей, а вот последние три строки позволяют удобно использовать виртуальные окружения, пример использования которых далее.
Использование виртуальных окружений
Создаём папку проекта (avox ожидает что все проекты лежат в $PROJECT_DIRS):
mkdir -p projects/testСоздаём виртуальное окружение для этого проекта:
vox new testБлагодаря настроенному дополнению avox нам достаточно перейти в папку проекта чтобы активировать виртуальное окружение, никаких странных source ./bin/activate выполнять не нужно:
worldmind@x ~ $ cd projects/test/
(test) worldmind@x ~/projects/test $ pip install see
...
(test) worldmind@x ~/projects/test $ python -c 'import see'По выходу из папки виртуальное окружение деактивируется:
(test) worldmind@x ~/projects/test $ cd
worldmind@x ~ $ python3 -c 'import see' err>out | fgrep 'NotFound'
ModuleNotFoundError: No module named 'see'Заодно можно увидеть более человеческую работу с перенаправлением потоков ввода-вывода, кто никогда не забывал как это делать во всяких башах пусть первым кинет в меня коментом.
Для полноты картины хотело бы, чтобы в этих виртуальных окружениях можно было бы использовать произвольную версию питона, например установленную через pyenv, но пока не срослось, а самому подкостылить руки не дошли.
UPD: Не так давно xonsh научили использовать произвольную версию питона в виртуальных окружениях.
Устанавливаем желаемую версию питона (список доступных pyenv install --list):
pyenv install 3.7.2Создаём виртуальное окружение с ней:
mkdir projects/projectwith3.7
vox new -p $PYENV_ROOT/versions/3.7.2/bin/python projectwith3.7Проверяем:
(projectwith3.7) worldmind@x ~/projects/projectwith3.7 $ python --version
Python 3.7.2Грабли
Единственное на что я накнулся это отличия в эскейпинге:
find . -name data.txt -exec echo {} \;не будет работать, ибо эскейпинг обратным слэшем не работает в xonsh и фигурные скобки имеют специальное значение, нужно использовать кавычки, например так:
find . -name .xonshrc -exec echo '{}' ';'некоторые отличия от bash есть в виде таблицы в документации.
Вывод
Мне кажется, что xonsh это хорошой претендент на нормальный шелл будущего для всех, а особенно он должен понравиться питонистам. Начните пользоваться (установка без sudo упрощает откат назад, можно просто удалить папку), чтобы понять всё ли там есть личн�� для вас, может это то, что вы искали, но боялись установить.
