LINUX.ORG.RU

Настраиваем и используем ZSH вместо Bash, или превращаем терминал в раскраску

 , ,

Настраиваем и используем ZSH вместо Bash, или превращаем терминал в раскраску

6

4

Я не буду расписывать преимущества ZSH над Bash, отмечу лишь то, что ZSH используется по дефолту во многих дистрибутивах Linux, а также с недавних пор и в macOS (тут должна быть шутка про Торвальдса и его макбук). Главной причиной повсеместной замены bash на zsh является встроенный механизм модулей, поверх которого было навалено такое великолепие, как Oh My Zsh.

Установка:

# В арчеподобных дистрах:
pacman -S zsh

# В дебианоподобных:
apt install zsh

Теперь нужно сделать zsh дефолтным шеллом:

chsh -s $(which zsh)

Главный конфиг zsh называется .zshrc, там можно, например, объявить пользовательские переменные окружения, но они будут доступны ТОЛЬКО В СЕССИИ ТЕРМИНАЛА. Чтобы они были доступны «везде», их нужно прописать в ~/.zshenv.

Кучу дотфайлов не очень удобно хранить в пользовательской директории, поэтому все конфиги лучше вынести в ~/.config/zsh.

Создадим директорию для конфигов zsh:

mkdir -p ~/.config/zsh

Теперь настроим переменные окружения

~/.zshenv:

# Для начала зададим переменные xdg, если те не заданы
# Эти переменные используются многими программами, и если их не задать, то пользовательская директория будет завалена файлами с точкой в начале имени 
# https://wiki.archlinux.org/title/XDG_Base_Directory
export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
export XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"

# Далее определим эту переменную, чтобы конфиги zsh искались в этой директории
export ZDOTDIR="${XDG_CONFIG_HOME}/zsh"

# Так же добавим пути до бинарников в домашнем каталоге в PATH
# и переместим .zfunc из домашней директории в $ZDOTDIR
typeset -U path fpath
path=(~/.local/bin ~/bin $path)
fpath+=("$ZDOTDIR/.zfunc")

Остальные переменные добавьте по желанию (которые должны быть доступны в программах типа VS Code и т.п., если те запускаются не из терминала).

❗❗❗ После изменения ~/.zshenv нужно сделать логаут и снова войти под тем же пользователем.

Я уже упомянул про легендарную систему модулей. Модулями (плагинами) легче всего управлять через менеджер плагинов. Я советую использовать antidote – реанкарнацию почившего в бозе antibody. Он позволяет очень просто управлять плагинами через текстовый файл.

Установка в Arch:

yay -S zsh-antidote

В остальных дистрах потребуется немного ручной работы:

git clone --depth=1 https://github.com/mattmc3/antidote.git ${ZDOTDIR:-~}/.antidote

Теперь перейдем к настройке главного конфига.

~/.config/zsh/.zshrc:

# Зададим путь до директории с плагинами Oh My Zsh
export ZSH="${ZDOTDIR}/oh-my-zsh"

# Вставка \ перед ? и тп
# Меня лично это бесит
DISABLE_MAGIC_FUNCTIONS=true

# Здесь подключается antidote

# Если antidote установлен через пакетный менеджер, то путь до него будет выглядеть примерно так
antidote_zsh='/usr/share/zsh-antidote.zsh'

# Если antidote был скачен через git, иначе закомментируйте следующую строку
antidote_zsh="$ZDOTDIR/.antidote/antidote.zsh"

if [ -f "$antidote_zsh" ]; then
  zsh_plugins=${ZDOTDIR:-$HOME}/.zsh_plugins
  if [[ ! ${zsh_plugins}.zsh -nt ${zsh_plugins}.txt ]]; then
    (
      source "$antidote_zsh"
      antidote bundle <${zsh_plugins}.txt >${zsh_plugins}.zsh
    )
  fi
  source ${zsh_plugins}.zsh
fi

# Настройки истории
export HISTSIZE=100000
export SAVEHIST=100000

# Файл истории так же храним в ~/.config/zsh
export HISTFILE=$ZDOTDIR/.zsh_history

# Всякие алиасы я предпочитаю хранить как файлы с расширением `.zsh` в ~/.config/zsh/zshrc.d

# Тут мы создаем директорию, если ее нет
if [ ! -d "$ZDOTDIR/zshrc.d" ]; then
  mkdir -p "$ZDOTDIR/zshrc.d"
fi

# А тут: подключаем вспомогательные файлы
for src in $ZDOTDIR/zshrc.d/*.zsh; do
  . "$src"
done

Минимальный конфиг готов.

А теперь пришло время настраивать и устанавливать все игр… плагины.

Antidote настраивается через текстовый файл. Где с каждой строчки указываются модули/плагины, которые нужно использовать, предварительно выкачав. Например, если плагин находится на https://github.com/zdharma-continuum/fast-syntax-highlighting, то мы указываем только часть после https://github.com/, те zdharma-continuum/fast-syntax-highlighting, если же плагин загружен на другой git-репозиторий исходного кода, то нужно добавить имя домена, например, gitlab.com/[username]/[reponame].

Создадим ~/.config/zsh/.zsh_plugins.txt:

# oh-my-zsh
# Подгрузим содержимое https://github.com/ohmyzsh/ohmyzsh/tree/master/lib
ohmyzsh/ohmyzsh path:lib

# Добавим какие-нибудь плагины
ohmyzsh/ohmyzsh path:plugins/colored-man-pages
ohmyzsh/ohmyzsh path:plugins/colorize
ohmyzsh/ohmyzsh path:plugins/command-not-found
ohmyzsh/ohmyzsh path:plugins/common-aliases

# мне еще нравится этот
# он позволяет добавить к текущей или предыдущей команде sudo, два раза нажав <ESC> 
ohmyzsh/ohmyzsh path:plugins/sudo

# этот плагин вставляет закрывающую кавычку или скобку при вводе открывающей...
hlissner/zsh-autopair

# уведомляет о том, что у команды есть алиас
MichaelAquilina/zsh-you-should-use

# подстановка ранее введеных команд
zsh-users/zsh-autosuggestions kind:defer

# автодополнение аргументов
zsh-users/zsh-completions kind:defer

# я обещал превратить терминал в раскраску...
# подсветка синтаксиса zsh (раскрашивание ключевых слов и прочих разделителей разными цветами)
zdharma-continuum/fast-syntax-highlighting kind:defer

# ну и поставим какую-нибудь тему
ohmyzsh/ohmyzsh path:themes/refined.zsh-theme

Скрины с темами можно посмотреть здесь.

Если не устраивают темы oh my zsh, то вот вам одна из самых популярных тем romkatv/powerlevel10k.

Осталось только перезапустить шелл:

exec -l $SHELL

Жду дополнений. Может, и для себя что-то новое узнаю.

Интересные плагины можно найти в репозитории Awesome ZSH Plugins.



Проверено: hobbit ()
Последнее исправление: rtxtxtrx (всего исправлений: 14)

Как по мне oh-my-zsh содержит в себе в основном мусор. У меня используется самописный конфиг + плагин zsh-autosuggestions, который делает пользование шеллом в разы удобнее, и плагин zsh-syntax-highlighting, который добавляет красоты.

Werenter ★★★
()
Последнее исправление: Werenter (всего исправлений: 2)

Поставил + теме. Сам как-то давно установил и пользуюсь grml-zsh-config, базовые фичи там присутствуют.

krasnh ★★★★
()
Последнее исправление: krasnh (всего исправлений: 1)
Ответ на: комментарий от artemlinux

Ну он этим хорош и плох одновременно, что небогатый функционал, который парой-тройкой плагинов добавляется в zsh встроенный, а в противовес — что новый и не добавишь

rtxtxtrx
() автор топика

Ставить дефолтным шеллом-то необязательно, надо просто ставить его дефолтным в терминале, потому что раскрашенный zsh немного толстый бывает, да и простой шелл как дефолтный даёт меньше беспокойства без потенциально ломающих конфигов.

И хз про остальных, но я свои XDG пути прописываю в ~/.profile

Bfgeshka ★★★★★
()
Ответ на: комментарий от Bfgeshka

да все эти *sh тормозные, тебе не нужна скорость в интерактивном шелле, ты сило мысли не печатаешь же

да и простой шелл как дефолтный даёт меньше беспокойства без потенциально ломающих конфигов

просто дефолтный конфиг загрузится с %

я не понял смысла первого абзаца

rtxtxtrx
() автор топика
Ответ на: комментарий от rtxtxtrx

Ну вот у меня есть mksh на логине и zsh в st. Если я что-то зачуханю в конфиге zsh (что реально происходило пару раз), моя система будет всё ещё прекрасно и предсказуемо работать - разве не хорошо?

Как крохотный бонус - mksh гораздо проще и легче, чем zsh+ohmyzsh, а ведь этот шелл всё время будет в памяти висеть.

Bfgeshka ★★★★★
()
Ответ на: комментарий от Bfgeshka

а ведь этот шелл всё время будет в памяти висеть

2-3 мегабайта сама по себе эта красота жрет… да и то это у меня. у меня и список плагинов побольше и еще куча всего

Если я что-то зачуханю в конфиге zsh

то тебе отобразится zsh с дефолтными настройками, корявый конфиг проигнорируется с выводом предупреждения вверху:

/home/имярек/.config/zsh/.zshrc:228: parse error near ...
имяхоста% 
rtxtxtrx
() автор топика
Ответ на: комментарий от rtxtxtrx

2-3 мегабайта сама по себе эта красота жрет… да и то это у меня. у меня и список плагинов побольше и еще куча всего

Ну это всего лишь 2 мегабайта в шелле, всего лишь 10 метров в UI приложении, ну лишний гигабайт в браузере - а когда эти допущения останавливаются? Это разгильдяйский менталитет, от которого аштрисёт. Если мой логин шелл может жить на двух мегабайтах вместо пяти, то почему нет?

то тебе отобразится zsh с дефолтными настройками

Неправильно. Это лишь ошибки парсера, а могут быть косяки помимо этого - закомментировал не ту строчку, установил плохую переменную окружения, итд. И вот если конфиг у zsh на логине отвалится и шелл загрузится «безопасно», то мой ~/.xinit уже не будет выполняться, а там весь автозапуск всего на свете, это будет нужно ручками теребонькать в tty - это надо кому? А зачем, ну ради чего?

Bfgeshka ★★★★★
()

вместо этой портянки можно просто уже поставить atuin + fzf в bash и больше не заморачиваться с zsh

TomBOY ★★
()
Ответ на: комментарий от artemlinux

Что люди не придумают лишь бы не использовать Fish

Fish отличный, но нестандартный shell-синтаксис убивает всю идею на корню. Нет, изменения синтаксиса правильные, только их нужно было сделать лет 30 назад, а сейчас уже поздно. Моей последней каплей стало ломание pkg-config – одно дело улучшенный синтаксис, и совсем другое, когда он ломает другие программы, которые даже от него не зависят.

Было бы отлично, если бы fish стал таким настроенным по умолчанию zsh, который не надо пердолить. Я бы пользовался.

MoldAndLimeHoney
()
Ответ на: комментарий от MoldAndLimeHoney

Fish отличный, но нестандартный shell-синтаксис убивает всю идею на корню. Нет, изменения синтаксиса правильные, только их нужно было сделать лет 30 назад, а сейчас уже поздно. Моей последней каплей стало ломание pkg-config – одно дело улучшенный синтаксис, и совсем другое, когда он ломает другие программы, которые даже от него не зависят.

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

altwazar ★★★★
()
Ответ на: комментарий от altwazar

Лично для меня, zsh только для удобств в терминале/консоли, а сами скрипты естественно на баше. Но вот, если бы я хотел fish для этих же же «удобств из коробки», то там уже нюансы с синтаксисом, которые могут вылезти прямо при наборе привычных команд в терминале, и об этом уже здесь сказали, и в других тредах читал:

Но условный однострочник for иногда проскакивает прям в терминале - чуть пришлось подучить разницу.
Закос... под NixOS (комментарий)

krasnh ★★★★
()
Ответ на: комментарий от altwazar

Использование новой строки в качестве разделителя редко приводит к неожиданным проблемам

Но приводит.

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

MoldAndLimeHoney
()
Ответ на: комментарий от MoldAndLimeHoney

Но приводит.

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

altwazar ★★★★
()
Ответ на: комментарий от artemlinux

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

Никаких новых контрибьюторов у них естественно не появилось.

Lrrr ★★★★★
()

fzf + bat оч удобно.

ggrn ★★★★★
()

Я с zsh откатился на tcsh. (=

mord0d ★★★★★
()

Ушёл на nushell, работает шустрее (пробовал на старом одноядернике, вполне комфортно), всё что нужно уже в нём, не надо убивать целый час на скачивание и настройку плагинов. Синтаксис у него не совмести с bash, но его идеи и удобства мне сильно пришлись по вкусу, какое-то время придётся привыкать.

nushell конечно не без косяков, написан на rust (это уже для кого как +/-), некоторых редких, но полезных фишек из bash не хватает. Ещё не вышла версия 1.0, с обновлениями частенько приходит слом синтаксиса, так что он пока явно не подходит для написания больших и сложных скриптов, скорее только в качестве удобной оболочки для терминала, а скрипты можно и на другом языке писать.

Dr64h ★★
()

Ну надо же. А я первым делом все это удалил:

$ paclog zsh

Date                Action  Package                 Version
----                ------  -------                 -------
30.05.2023 23:18:48 removed arcolinux-zsh-git       23.04-07
30.05.2023 23:18:48 removed oh-my-zsh-git           r6905.fb4213c34-1
30.05.2023 23:18:48 removed zsh                     5.9-3
30.05.2023 23:18:48 removed zsh-completions         0.34.0-4
30.05.2023 23:18:48 removed zsh-syntax-highlighting 0.7.1-1

dmitry237 ★★★
()
Ответ на: комментарий от TomBOY

atuin + fzf

это всего лишь поиск по истории. не знаю что ты хотел этим сказать, и как оно превратит «терминал в раскраску». я думаю тебе нужно осилить использование менеджеров сниппетов для терминала типа pet и тогда не придется в историю постоянно лазать

rtxtxtrx
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от ox55ff

плагины для zsh на zsh. K.O. я написал уже чем плох fish (не говоря уже о том, что он полумертв и отсутствия обратной совместимости с bash с его for ... end). xosh, nushell и тп - это все из одной оперы. все выглядят достойно пока не потребуется кастомизация и/или постоянная работа с терминалом, и тогда вылезут все-все проблемы с которыми не встретишься в bash, zsh или даже том mksh (бздюшный шелл) (банально нельзя скопипастить однострок на баше - синтаксис уже другой). fish - это старая тема. он появился в середине нулевых и показал каким должен быть удобный шелл, повлиял на тот же zsh, но не смог убить последний. есть хоть один дистр перешедший на рыбу?

rtxtxtrx
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 2)

В fish есть:

  • открытие man по F1 для комманды, которую ты набираешь
  • abbreviations - когда ты написал pm, нажал пробел и оно раскрылось в pacman
  • встроенные функции для строк и парсинга

Также не приходится забивать голову навешиванием кавычек на переменные и выхлоп комманд, в которых может содержаться пробел. Ну и в принципе если писать цикл из терминала в bash/zsh я бы скорее не стал, то в fish его писать попроще и оно динамически добавляет отступы в процессе набора.

А zsh для додиков.

fumanchez
()
Ответ на: комментарий от dataman

Странно что еще растоманской версии не написали

rtxtxtrx
() автор топика

Мне всегда было интересно - а не тормозит ли zsh от этих всех модулей? Я zsh пользуюсь очень давно, но при этом ничем таким не пользуюсь, по сути он мне нужен главным образом для правого промпта.

% time zsh -i -c true
Restored session: Sat  6 Jul 2024 06:07:26 +05

Saving session...completed.
zsh -i -c true  0.03s user 0.03s system 88% cpu 0.065 total

У вас сколько выдаёт эта команда со всеми этими плагинами?

vbr ★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от fumanchez

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

А где нужно навешивать кавычки, если мы говорим про zsh? Я сходу даже и не припомню.

% a='b c'

% printf '"%s" ' $a
"b c" %                                                                         
% printf '"%s" ' b c
"b" "c" %                                                                       

% a=

% if [[ $a = '' ]] { print eq } else { print neq }
eq
vbr ★★★★
()
Последнее исправление: vbr (всего исправлений: 3)
Ответ на: комментарий от vbr

❯ time zsh -i -c true
zsh -i -c true 0.09s user 0.08s system 103% cpu 0.173 total

rtxtxtrx
() автор топика
Ответ на: комментарий от vbr

zsh -i -c true 0,38s user 0,11s system 100% cpu 0,496 total

У меня довольно долго, несмотря на то, что плагинов у меня немного. Предполагаю, что дело в HDD.

Werenter ★★★
()
Ответ на: комментарий от Ja-Ja-Hey-Ho

А при ресайзе окна терминала форматирование текста адаптивное или нет? Например ввел команду с выводом на всю ширину хоста, а потом изменил его размер, подстроится этот текст под новые размеры или нет?

До ресайза
После

dmitry237 ★★★
()
Ответ на: комментарий от fumanchez

abbreviations - когда ты написал pm, нажал пробел и оно раскрылось в pacman

Идея хорошая, только вот which не показывает, что оно делает. Если я сделал alias в bash/zsh, я могу просто выполнить which и узнать что алиас делает.

❯ which dnf.list_package_files
dnf.list_package_files='sudo dnf repoquery --list'
	/usr/bin/sudo

А вот abbr так не может, нужно по конфигам искать что оно такое.

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

❯ dnf.<Tab>
dnf.history_info        dnf.remove            
dnf.history_list        dnf.repo_disable      
dnf.info                dnf.repolist          
dnf.install             dnf.requires          
dnf.list_installed      dnf.search            
dnf.list_package_files  dnf.upgrade           
dnf.provides            dnf.whatrequires

Зачем мне раскрывать эти команды?

Только представь, что оно мне постоянно будет раскрывать ls в полную срань:

❯ which ls                    
ls='ls --color=auto --human-readable --group-directories-first --classify'
	/usr/bin/ls

Я использовал abbr в fish, киллерфичей показалось возможность добавить docstring, но отказался по вышеперечисленным причинам.

MoldAndLimeHoney
()
Ответ на: комментарий от rtxtxtrx

Раскраска нужна, если ты занят раскраской, а если нужно быстро порешать вопросики, то цвет терминала перестаёт иметь концептуальное значение.

TomBOY ★★
()
Ответ на: комментарий от TomBOY

если нужно быстро порешать вопросики, то цвет терминала

Позволяет быстро уловить взглядом нужное и серьёзно экономить время, ибо одноцветные bash-полотнища нуждаются в больших затратах времени и сил на парсинг мозгом.

EXL ★★★★★
()
Ответ на: комментарий от rtxtxtrx

есть хоть один дистр перешедший на рыбу?

Никто не будет ставить в дистр по умолчанию нестандартный шелл без баш совместимости, это уже будет не gnu linux, а уходящая от стандартов, несовместимая со скриптами и командами маргинальщина.

Dr64h ★★
()
Ответ на: комментарий от Dr64h

zsh тоже нестандартный как и korn и тп. у них у всех «особенности» и «плохая генетика», что верно и для рыбы, но ее почему-то не используют… почему? я уж молчу про повер щель, которая лучшей всей этой башепараши


да и баш тоже не везде используется. в initrd и тп используется ash с более «строгим» синтаксисом

rtxtxtrx
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от rtxtxtrx

zsh, korn, ash (в линуксах был заменён на dash), все они как минимум реализовывают sh, то есть соответствуют POSIX. fish, nushell и прочие новомодные, идут по своему пути, реализуют свой несовместимый синтаксис, поэтому если их и добавят в какие-то дистрибутивы, то только в качестве второго шелла, исключение только совсем маргинальные и экспериментальные дистры, где могут любой стандартный компонент поменять на что-то инное.

да и баш тоже не везде используется. в initrd и тп используется ash с более «строгим» синтаксисом

Это уже специфичные случаи, выходящие за рамки контекста.

Dr64h ★★
()
Ответ на: комментарий от MoldAndLimeHoney

Идея хорошая, только вот which не показывает, что оно делает

И не должно, это просто текст, который раскрывается в другой текст.

Только представь, что оно мне постоянно будет раскрывать ls в полную срань

Это костыль, чтобы передать флаги, less к примеру умеет брать дефолтные флаги из окружения. Сценарий применения аббревиатур другой - это набор команд типа git commit, чтобы не засирать историю и не создавать двусмысленность на ровном месте.

Зачем мне раскрывать эти команды?

Алиасы для dnf это уже бред, он и так на каждую команду имеет по алиасу, получить трехэтажную команду как ls для dnf практически невозможно.

fumanchez
()
Ответ на: комментарий от vbr

А где нужно навешивать кавычки, если мы говорим про zsh?

Да любую переменную раскрываешь, и если там есть пробел, то она превращается в 2 токена. Если ты пишешь что-то типа

rm -f $path

а не

rm -f "$path"

то это отстрел ноги. В fish это все неактуально, можно писать без кавычек.

fumanchez
()
Ответ на: комментарий от fumanchez

Давно проверял? А то вводишь людей тут в заблуждение

rtxtxtrx
() автор топика
Ответ на: комментарий от vbr

Ок, это не так, я думал это как минимум не дефолт для позиксного шелла. Но вопрос с command substitution не раскрыт, в fish rm (cmd) экранировать не надо.

fumanchez
()
Ответ на: комментарий от rtxtxtrx

(банально нельзя скопипастить однострок на баше - синтаксис уже другой)

Ерунда, bash -c ‘for; do; done твой однострок’

У меня фиш, а env общий на баш и на fish в башевом формате, подгружается в fish через foreign-env

masa
()
Ответ на: комментарий от masa

А если там кавычки? Править будешь, да? С сектантами фиша бесполезно спорить, но человек, использующий последний как минимум расписывается в неосиляторстве настроить zsh или bash (его тоже можно красивым сделать, но это на порядки сложнее)

rtxtxtrx
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.