Zsh (Русский)

From ArchWiki
Состояние перевода: На этой странице представлен перевод статьи Zsh. Дата последней синхронизации: 29 сентября 2023. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Zsh является мощной современной оболочкой, которая работает как в интерактивном режиме, так и в качестве интерпретатора языка сценариев. Он совместим с bash (не по умолчанию, только в режиме emulate sh), но имеет преимущества, такие как улучшенное завершение и подстановка.

Еще больше причин, по которым стоит использовать Zsh, перечислено в Zsh FAQ EN.

Установка

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

$ echo $SHELL

Установите пакет zsh. Чтобы значительно расширить возможности автодополнения команд, установите также пакет zsh-completions.

Первоначальная настройка

Убедитесь, что Zsh был установлен правильно, выполнив следующую команду в терминале:

$ zsh

После этого вы должны увидеть скрипт zsh-newuser-install, который проведет вас через некоторые основные настройки. Если вы хотите пропустить первичную настройку, нажмите q. Если скрипт не запустился, вы можете вызвать его вручную:

$ autoload -Uz zsh-newuser-install
$ zsh-newuser-install -f
Примечание: Для работы zsh-newuser-install требуется терминал размером не менее 72×15 символов.

Установка Zsh в качестве оболочки по умолчанию

Вы можете изменить оболочку по умолчанию на /usr/bin/zsh. Смотрите раздел Командная оболочка#Выбор оболочки по умолчанию.

Совет: При замене bash на Zsh можно перенести некоторые участки кода из ~/.bashrc в ~/.zshrc (например, приглашение командной строки и псевдонимы), а также из ~/.bash_profile в ~/.zprofile (например, код, который запускает оконную систему X).

Файлы запуска/завершения

Совет: Руководство пользователя Z-Shell содержит информацию об интерактивных оболочках и оболочках входа и о том, что помещать в файлы запуска.
Примечание:
  • Если $ZDOTDIR не определена, используется $HOME по умолчанию.
  • Если опция RCS удаляется в одном из файлов, никакие файлы конфигурации больше не будут прочитаны после этого файла.
  • Если опция GLOBAL_RCS удаляется в одном из файлов, никакие глобальные файлы конфигурации (/etc/zsh/*) не будут прочитаны после этого файла.

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

  • /etc/zsh/zshenv — используется для установки переменных окружения для всех пользователей; он не должен содержать команд, которые производят вывод или предполагают, что shell подключен к TTY. Если файл существует, он всегда будет прочитан, это нельзя переопределить.
  • $ZDOTDIR/.zshenv — используется для установки переменных окружения текущего пользователя; он не должен содержать команд, которые производят вывод или предполагают, что shell подключен к TTY. Если файл существует, он всегда будет прочитан.
  • /etc/zsh/zprofile — используется для выполнения команд для всех пользователей, будет прочитан при запуске оболочки входа. Обратите внимание, что в Arch Linux по умолчанию он содержит одну строку, считывающую /etc/profile.
    • /etc/profile — этот файл должен быть прочитан всеми POSIX sh-совместимыми оболочками при входе в систему: он устанавливает $PATH и другие переменные окружения, а также специфичные для приложения (/etc/profile.d/*.sh) настройки при входе в систему.
  • $ZDOTDIR/.zprofile — используется для выполнения команд текущего пользователя, будет прочитан при запуске оболочки входа. Обычно используется для автозапуска графического сеанса или установки переменных окружения для сеанса.
  • /etc/zsh/zshrc — используется для настройки интерактивной конфигурации оболочки и выполнения команд для всех пользователей, будет прочитан при запуске интерактивной оболочки.
  • $ZDOTDIR/.zshrc — используется для настройки интерактивной конфигурации и выполнения команд текущего пользователя, будет прочитан при запуске интерактивной оболочки.
  • /etc/zsh/zlogin — используется для выполнения команд для всех пользователей при завершении прогресса инициализации, будет прочитан при запуске оболочки входа.
  • $ZDOTDIR/.zlogin — используется для выполнения команд текущего пользователя при завершении прогресса инициализации, будет вызван при запуске оболочки входа. Не следует использовать для автозапуска графического сеанса, так как в этот момент сеанс может содержать конфигурацию, предназначенную только для интерактивной оболочки.
  • $ZDOTDIR/.zlogout — используется для выполнения команд текущего пользователя при завершении работы оболочки входа.
  • /etc/zsh/zlogout — используется для выполнения команд для всех пользователей при завершении работы оболочки входа.

Смотрите также графическое представление.

Примечание: $HOME/.profile не относится к файлам запуска Zsh и не используется, если Zsh не запускается как оболочка входа sh или ksh. Более подробную информацию о режимах совместимости sh и ksh смотрите в zsh(1) § COMPATIBILITY.
Важно: Не рекомендуется убирать стандартную одну строку в /etc/zsh/zprofile, так как это нарушит интеграцию с пакетами, которые устанавливают свои скрипты в /etc/profile.d.

Настройка Zsh

Хотя Zsh может использоваться “из коробки”, он настроен не так, как хотело бы большинство пользователей. Из-за наличия огромных возможностей настройки, доступных в Zsh, этот процесс может оказаться сложным и трудоемким. Для автоматической настройки можно использовать #Сторонние расширения.

Простой .zshrc

Ниже приведён пример файла настроек, который обеспечивает достойный набор опций по умолчанию, а также предоставляет примеры многих вариантов настройки Zsh. Для того, чтобы использовать этот пример, сохраните его в виде файла с именем .zshrc.

Совет: Чтобы применить изменения не завершая сеанс, выполните команду source ~/.zshrc

Вот простой .zshrc:

~/.zshrc
autoload -Uz compinit promptinit
compinit
promptinit

# Эта настройка установит тему walters для приглашения командной строки
prompt walters

Подробности о темах приглашений командной строки описаны в разделе #Темы строк приглашений.

Настройка переменной $PATH

Zsh связывает переменную PATH с массивом path. Это позволяет вам менять PATH, просто изменяя массив path. Подробности смотрите в руководстве пользователя Z-Shell.

Чтобы добавить ~/.local/bin/ в PATH:

~/.zshenv
typeset -U path PATH
path=(~/.local/bin $path)
export PATH

Автозавершение команд

Возможно, наиболее убедительной стороной Zsh является его передовые возможности автозавершения. Включите автозавершение в .zshrc. Добавив следующую строку в ваш ~/.zshrc:

~/.zshrc
autoload -Uz compinit
compinit

Настройки выше включают в себя также автодополнение хостов ssh/scp/sftp, но для того, чтобы эта функция работала, пользователи не должны включать хеширование имён SSH-хостов в ~/.ssh/known_hosts (опция HashKnownHosts).

Для автодополнения с помощью меню, управляемом клавишами-стрелками, добавьте следующую строку:

~/.zshrc
zstyle ':completion:*' menu select

Для активации меню нажмите Tab дважды.

Чтобы автодополнение для привилегированных команд выполнялось в привилегированном окружении (например, если вы вводите команду через sudo, то скрипты автодополнения тоже будут запущены через sudo), добавьте:

~/.zshrc
zstyle ':completion::complete:*' gain-privileges 1
Важно: Это означает, что скрипты автодополнения Zsh будут выполнять команды с привилегиями sudo. Не включайте это, если вы используете недоверенные скрипты автодополнения.
Примечание: Это поддерживается для очень небольшого числа команд.

Назначение клавиш

Zsh не использует Readline, вместо этого он использует свой собственный и более мощный ZLE. Т.е. не читает /etc/inputrc или ~/.inputrc. Введение в настройку ZLE: A closer look at the zsh line editor and creating custom widgets.

ZLE имеет режимы Emacs и vi. По умолчанию он проверяет переменные окружения VISUAL и EDITOR: если одна из них содержит vi, то будет использоваться режим vi; в противном случае по умолчанию будет Emacs. Переключить режим можно с помощью команд bindkey -e или bindkey -v для режима Emacs или режима vi соответственно. Задержка при нажатии клавиши Esc в режиме vi по умолчанию составляет 0,4 с, но её можно сделать короче (0,05 с) через export KEYTIMEOUT=5.

Сочетания клавиш назначаются путём сопоставления escape-последовательности, соответствующей нажатию клавиши, виджету ZLE. Доступные виджеты с описанием их действий и привязок по умолчанию перечислены в zshzle(1) § STANDARD WIDGETS и zshcontrib(1) § ZLE FUNCTIONS.

Смотрите также zshwiki: bindkeys.

Рекомендуемый способ установки сочетаний клавиш в Zsh — чтение поддерживаемых escape-последовательностей из terminfo(5). Например[1]:

~/.zshrc
# Создание хэш-таблицы, совместимой с zkbd.
# Информацию о всех доступных клавишах можно узнать в man 5 terminfo
typeset -g -A key

key[Home]="${terminfo[khome]}"
key[End]="${terminfo[kend]}"
key[Insert]="${terminfo[kich1]}"
key[Backspace]="${terminfo[kbs]}"
key[Delete]="${terminfo[kdch1]}"
key[Up]="${terminfo[kcuu1]}"
key[Down]="${terminfo[kcud1]}"
key[Left]="${terminfo[kcub1]}"
key[Right]="${terminfo[kcuf1]}"
key[PageUp]="${terminfo[kpp]}"
key[PageDown]="${terminfo[knp]}"
key[Shift-Tab]="${terminfo[kcbt]}"

# Назначение действий поддерживаемым клавишам
[[ -n "${key[Home]}"      ]] && bindkey -- "${key[Home]}"       beginning-of-line
[[ -n "${key[End]}"       ]] && bindkey -- "${key[End]}"        end-of-line
[[ -n "${key[Insert]}"    ]] && bindkey -- "${key[Insert]}"     overwrite-mode
[[ -n "${key[Backspace]}" ]] && bindkey -- "${key[Backspace]}"  backward-delete-char
[[ -n "${key[Delete]}"    ]] && bindkey -- "${key[Delete]}"     delete-char
[[ -n "${key[Up]}"        ]] && bindkey -- "${key[Up]}"         up-line-or-history
[[ -n "${key[Down]}"      ]] && bindkey -- "${key[Down]}"       down-line-or-history
[[ -n "${key[Left]}"      ]] && bindkey -- "${key[Left]}"       backward-char
[[ -n "${key[Right]}"     ]] && bindkey -- "${key[Right]}"      forward-char
[[ -n "${key[PageUp]}"    ]] && bindkey -- "${key[PageUp]}"     beginning-of-buffer-or-history
[[ -n "${key[PageDown]}"  ]] && bindkey -- "${key[PageDown]}"   end-of-buffer-or-history
[[ -n "${key[Shift-Tab]}" ]] && bindkey -- "${key[Shift-Tab]}"  reverse-menu-complete

# Наконец, нужно убедиться, что терминал находится в application mode, когда
# zle активен. Только в этом случае значения из $terminfo будут действительны.
if (( ${+terminfo[smkx]} && ${+terminfo[rmkx]} )); then
	autoload -Uz add-zle-hook-widget
	function zle_application_mode_start { echoti smkx }
	function zle_application_mode_stop { echoti rmkx }
	add-zle-hook-widget -Uz zle-line-init zle_application_mode_start
	add-zle-hook-widget -Uz zle-line-finish zle_application_mode_stop
fi

Поиск по истории

Сперва создайте хэш-таблицу key и переведите ZLE в application mode, как описано в разделе #Назначение клавиш.

Добавьте эти строки в .zshrc

~/.zshrc
autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search

[[ -n "${key[Up]}"   ]] && bindkey -- "${key[Up]}"   up-line-or-beginning-search
[[ -n "${key[Down]}" ]] && bindkey -- "${key[Down]}" down-line-or-beginning-search

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

Модификаторы Shift, Alt, Ctrl и Meta

В xterm-совместимых терминалах можно использовать расширенные определения клавиш из user_caps(5). Это комбинации клавиш Shift, Alt, Ctrl и Meta вместе Up, Down, Left, Right, PageUp, PageDown, Home, End или Del. Список рекомендуемых названий клавиш-модификаторов и комбинаций клавиш смотрите в zkbd source.

Например, чтобы Ctrl+Left выполнял переход к началу предыдущего слова, а Ctrl+Right — к началу следующего слова:

~/.zshrc
key[Control-Left]="${terminfo[kLFT5]}"
key[Control-Right]="${terminfo[kRIT5]}"

[[ -n "${key[Control-Left]}"  ]] && bindkey -- "${key[Control-Left]}"  backward-word
[[ -n "${key[Control-Right]}" ]] && bindkey -- "${key[Control-Right]}" forward-word

Приглашения

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

Темы строк приглашений

Темы — это быстрый и лёгкий способ создать цветное приглашение в Zsh. Информация о темах и об их создании есть в zshcontrib(1) § PROMPT THEMES.

Для использования темы убедитесь, что prompt установлен в autoload в файле .zshrc. Это может быть сделано путём добавления этих строк:

~/.zshrc
autoload -Uz promptinit
promptinit

Посмотреть список доступных цветных тем можно с помощью команды:

$ prompt -l

Для просмотра всех доступных тем (с примерами), используйте команду:

$ prompt -p

Например, чтобы использовать цветовую схему bigfade, введите:

$ prompt bigfade

Чтобы использовать цветовую схему с заданным цветом (если доступен в теме), введите:

$ prompt elite2 blue
Установка тем вручную

Существует возможность установки тем вручную, без использования внешних инструментов. Для локальной установки сначала создайте каталог и добавьте его в массив fpath, например:

$ mkdir ~/.zprompts
$ fpath=("$HOME/.zprompts" "$fpath[@]")

Затем в этом каталоге создайте символическую ссылку на файл темы:

$ ln -s mytheme.zsh ~/.zprompts/prompt_mytheme_setup

Или если вы хотите установить тему глобально:

# ln -s mytheme.zsh /usr/share/zsh/functions/Prompts/prompt_mytheme_setup

После этого тему можно будет активировать:

$ prompt mytheme

Если сработает, можно записать это в .zshrc.

Добавление темы без создания отдельного файла

Помимо создания темы в отдельном файле, можно добавить тему внутри другого файла (например, в вашем .zshrc):

~/.zshrc
# Загрузка promptinit
autoload -Uz promptinit && promptinit

# Создание темы
prompt_mytheme_setup() {
  PS1="%~%# "
}

# Добавление темы в promptsys
prompt_themes+=( mytheme )

# Загрузка темы
prompt mytheme

Настройка строки приглашения

В дополнение к приглашению слева PS1 (PROMPT, prompt), которое используется в большинстве командных оболочек, Zsh также поддерживает приглашение справа RPS1 (RPROMPT). Эти две переменные используются для установки произвольного приглашения командной строки.

Другие приглашения специального назначения, например PS2 (PROMPT2), PS3 (PROMPT3), PS4 (PROMPT4), RPS1 (RPROMPT), RPS2 (RPROMPT2) и SPROMPT, описаны в zshparam(1) § PARAMETERS USED BY THE SHELL.

Приглашения командной строки поддерживают специальные управляющие последовательности (escapes), которые описаны в zshmisc(1) § EXPANSION OF PROMPT SEQUENCES. Некоторые примеры:

%n - Имя пользователя %m - Имя компьютера (до первой точки) %M - Полное имя компьютера %~ - Путь к текущему каталогу относительно домашнего %d - Полный путь к текущей директории ($PWD) %T - Время в формате HH:MM %* - Время в формате HH:MM:SS %D - Дата в формате YY-MM-DD %B, %b - Начало и конец выделения жирным

Цвета

Zsh устанавливает цвета иначе, чем Bash; вам не нужно возиться ANSI-кодами или с terminfo(5). Zsh предоставляет удобные управляющие последовательности для установки основного и фонового цветов и других визуальных эффектов; их список и описание приведены в zshmisc(1) § Visual effects.

Цвет может быть задан десятичным целым числом, названием одного из восьми наиболее широко поддерживаемых цветов или символом #, за которым следует триплет RGB в шестнадцатеричном формате. Подробнее в описании параметра fg=colour в zshzle(1) § CHARACTER HIGHLIGHTING.

Большинство терминалов поддерживают следующие цвета по названиям:

Название Цвет
black 0
red 1
green 2
yellow 3
blue 4
magenta 5
cyan 6
white 7

Для терминалов, поддерживающих 256 цветов, можно использовать номера 0–255: смотрите xterm-256color chart.

При правильно заданной переменной окружения TERM поддерживаемое терминалом максимальное количество цветов можно узнать из базы данных terminfo(5) с помощью команды echoti colors. Для 24-битных цветов также проверьте переменную окружения COLORTERM командой print $COLORTERM. Если она выведет 24bit или truecolor, то ваш терминал поддерживает 16777216 (224) цветов, даже если terminfo показывает меньшее число.

Примечание:
  • Цвета 0–15 могут быть разными в зависимости от используемого эмулятора терминала и пользовательских настроек.
  • Многие эмуляторы терминала отображают жирный текст более ярким цветом.
Совет:
  • Протестировать управляющие последовательности можно командой print -P "строка с escape-последовательностями", например:
    $ print -P '%B%F{red}цв%F{green}ет%F{blue}а!%f%b'
  • Если вы используете 24-битные цвета, может быть полезно загрузить модуль zsh/nearcolor для работы в терминалах, которые их не поддерживают. Например:
    [[ "$COLORTERM" == (24bit|truecolor) || "${terminfo[colors]}" -eq '16777216' ]] || zmodload zsh/nearcolor
    Смотрите zshmodules(1) § THE ZSH/NEARCOLOR MODULE для более подробной информации об этом модуле.
Пример

Пример простого приглашения командной строки без цветов:

PROMPT='%n@%m %~ %# '

Оно будет отображаться так:

username@host ~ %

Пример использования двухстороннего приглашения с цветами:

PROMPT='%F{green}%n%f@%F{magenta}%m%f %F{blue}%B%~%b%f %# '
RPROMPT='[%F{yellow}%?%f]'

А вот как оно будет отображаться:

username@host ~ % [0]

Для использования цветов из диапазона 16-255 и 24-битного true color можно использовать число от 0 до 255, присвоенное нужному цвету, и его шестнадцатеричный код цвета соответственно:

PROMPT='%F{2}%n%f@%F{5}%m%f %F{4}%B%~%b%f %# '
RPROMPT='[%F{3}%?%f]'
PROMPT='%F{#c0c0c0}%n%f@%F{#008000}%m%f %F{#800080}%B%~%b%f %# '
RPROMPT='[%F{#0000ff}%?%f]'

Примеры файла .zshrc

  • Пакет grml-zsh-config, доступный в официальном репозитории взятый с https://grml.org/zsh содержит zshrc файл, который включает в себя множество настроек для Zshell. Эта настройка используется по умолчанию для ежемесячного ISO релиза.
  • Базовая настройка с динамической строкой приглашения (Prompt) и заголовком окна / Hardinfo => https://github.com/MrElendig/dotfiles-alice/blob/master/.zshrc;
  • https://github.com/slashbeast/conf-mgmt/blob/master/roles/home_files/files/DOTzshrc - zshrc с несколькими функциями, - смотрите комментарии в файле. Известные особенности: подтверждение выключения, если пользователь запустил poweroff, а также запрос подтверждения на reboot или hibernate, поддержка GIT в Prompt (сделано без vcsinfo), завершение по TAB с меню, вывод текущей выполняемой команды в заголовке окна, и многое другое.

Смотрите также dotfiles#User repositories.

Советы и рекомендации

Автозапуск X при входе в систему

Смотрите xinit (Русский)#Автозапуск X при входе в систему.

Восстановление настроек терминала после аварийного завершения программы

Некоторые программы, меняющие состояние терминала, не восстанавливают его изначальные настройки после нештатного завершения (например, при вылете или получении сигнала SIGINT).

Это обычно решается с помощью reset(1):

$ reset

В следующих подразделах описаны способы решения, не требующие ручного сброса терминала.

Команда ttyctl

С помощью команды ttyctl можно «заморозить» и «разморозить» терминал. Для заморозки интерактивной оболочки при запуске:

~/.zshrc
ttyctl -f

Сброс терминала с помощью управляющих последовательностей

Альтернативный набор символов может испортить работу терминала так, что ttyctl не сможет этого предотвратить.

Простым решением является вывод escape-последовательностей, сбрасывающих терминал, через хук precmd, чтобы они выполнялись каждый раз перед выводом приглашения. Например, с помощью управляющей последовательности \e[0m\e(B\e)0\017\e[?5l\e7\e[0;0r\e8:

~/.zshrc
autoload -Uz add-zsh-hook

function reset_broken_terminal () {
	printf '%b' '\e[0m\e(B\e)0\017\e[?5l\e7\e[0;0r\e8'
}

add-zsh-hook -Uz precmd reset_broken_terminal

Для проверки работоспособности выполните:

$ print '\e(0\e)B'

Запоминание недавних каталогов

Dirstack

Zsh можно настроить, чтобы он помнил DIRSTACKSIZE (последние посещённые каталоги). Это пригодится для более быстрой работы с cd. Вам нужно добавить несколько строк, в файл настройки:

~/.zshrc
autoload -Uz add-zsh-hook

DIRSTACKFILE="${XDG_CACHE_HOME:-$HOME/.cache}/zsh/dirs"
if [[ -f "$DIRSTACKFILE" ]] && (( ${#dirstack} == 0 )); then
	dirstack=("${(@f)"$(< "$DIRSTACKFILE")"}")
	[[ -d "${dirstack[1]}" ]] && cd -- "${dirstack[1]}"
fi
chpwd_dirstack() {
	print -l -- "$PWD" "${(u)dirstack[@]}" > "$DIRSTACKFILE"
}
add-zsh-hook -Uz chpwd chpwd_dirstack

DIRSTACKSIZE='20'

setopt AUTO_PUSHD PUSHD_SILENT PUSHD_TO_HOME

## Удалить повторяющиеся записи
setopt PUSHD_IGNORE_DUPS

## Это Отменяет +/- операторы.
setopt PUSHD_MINUS

Теперь используйте

dirs -v

Для вывода стека директорий. Используйте cd -<NUM> чтобы вернуться к посещённому каталогу. Используйте автозавершение (нажав TAB) после тире.

Примечание: Это не будет работать, если у вас открыто более одной сессии zsh, и использование cd, приведёт к конфликту в обоих ссессиях пишущих в тот же файл.

cdr

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

Смотрите zshcontrib(1) § REMEMBERING RECENT DIRECTORIES.

zoxide

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

Команда Help

В отличие от bash, в Zsh не предусмотрена встроенная команда help, вместо неё используется run-help. По умолчанию run-help является псевдонимом команды man, её можно либо выполнить вручную, добавив к команде, либо вызвать для текущей команды с помощью сочетаний клавиш Alt+h или Esc h.

Поскольку по умолчанию это всего лишь псевдоним на man, она будет работать только с внешними командами. Для улучшения функциональности, чтобы она работала со встроенными командами оболочки и другими её возможностями, нужно использовать функцию run-help. Более подробная информация о run-help и вспомогательных функциях есть в zshcontrib(1).

Сначала загрузите функцию run-help, а затем удалите существующий псевдоним run-help. Для удобства можно сделать help псевдонимом run-help. Например, добавьте следующие строки в ваш zshrc:

autoload -Uz run-help
(( ${+aliases[run-help]} )) && unalias run-help
alias help=run-help

Вспомогательные функции нужно включить отдельно:

autoload -Uz run-help-git run-help-ip run-help-openssl run-help-p4 run-help-sudo run-help-svk run-help-svn

Теперь, например, команда run-help git commit будет открывать man-страницу git-commit(1), а не просто git(1).

Постоянный rehash

Как правило, compinit не будет автоматически находить новые исполняемые файлы в $PATH. Например, после установки нового пакета файлы в каталоге /usr/bin/ не появятся в автодополнении сразу. Для их появления нужно выполнить команду:

$ rehash

Её можно запускать автоматически.[2] Просто добавьте в ваш zshrc:

~/.zshrc
zstyle ':completion:*' rehash true

Выполнение rehash по необходимости

С помощью хуков можно настроить pacman на запуск rehash после установки или удаления пакетов, что позволит избежать снижения производительности из-за постоянного запуска rehash описанным выше способом. Создайте каталоги /etc/pacman.d/hooks и /var/cache/zsh, а затем создайте хук:

/etc/pacman.d/hooks/zsh.hook
[Trigger]
Operation = Install
Operation = Upgrade
Operation = Remove
Type = Path
Target = usr/bin/*
[Action]
Depends = zsh
When = PostTransaction
Exec = /usr/bin/install -Dm644 /dev/null /var/cache/zsh/pacman

Он будет обновлять дату изменения файла /var/cache/zsh/pacman каждый раз при установке, обновлении или удалении пакетов. Теперь нужно заставить Zsh обновить свой кэш команд, когда он устареет. Добавьте в ~/.zshrc:

~/.zshrc
zshcache_time="$(date +%s%N)"

autoload -Uz add-zsh-hook

rehash_precmd() {
  if [[ -a /var/cache/zsh/pacman ]]; then
    local paccache_time="$(date -r /var/cache/zsh/pacman +%s%N)"
    if (( zshcache_time < paccache_time )); then
      rehash
      zshcache_time="$paccache_time"
    fi
  fi
}

add-zsh-hook -Uz precmd rehash_precmd

Если хук precmd срабатывает до того, как дата у файла /var/cache/zsh/pacman обновится, то автодополнение может выдавать устаревшие данные до тех пор, пока не будет запущено новое приглашение. Для этого достаточно выполнить пустую команду, например, нажать enter.

Выполнение rehash по необходимости с помощью SIGUSR1

Аналогично описанному выше, но хук теперь такой:

/etc/pacman.d/hooks/zsh-rehash.hook
[Trigger]
Operation = Install
Operation = Upgrade
Operation = Remove
Type = Path
Target = usr/bin/*

[Action]
Depends = zsh
Depends = procps-ng
When = PostTransaction
Exec = /usr/bin/pkill zsh --signal=USR1
Важно: Он отправит SIGUSR1 всем запущенным экземплярам zsh. Обратите внимание, что по умолчанию SIGUSR1 завершает процесс, поэтому при первой настройке все запущенные экземпляры zsh у всех пользователей (в том числе оболочки входа) будут завершены, если они не применили описанную ниже настройку.
~/.zshrc
TRAPUSR1() { rehash }

Вместо функции можно использовать trap 'rehash' USR1. Об отличиях между этими двумя способами можно почитать в zshmisc(1) § Trap Functions.

Этот метод будет запускать rehash во всех экземплярах zsh сразу, избавляя от необходимости нажимать enter для запуска precmd.

Назначение клавиши в ncurses

Привяжите приложение ncurses к keystoke, но оно не будет принимать взаимодействие. Используйте переменную BUFFER, чтобы заставить его работать. Следующий пример позволяет пользователям открывать ncmpcpp, используя Alt+\:

~/.zshrc
ncmpcppShow() {
  BUFFER="ncmpcpp"
  zle accept-line
}
zle -N ncmpcppShow
bindkey '^[\' ncmpcppShow

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

~/.zshrc
ncmpcppShow() {
  ncmpcpp <$TTY
  zle redisplay
}
zle -N ncmpcppShow
bindkey '^[\' ncmpcppShow

Горячие клавиши как в файловом менеджере

Могут пригодится настройки клавиш использующиеся в графическом файловом менеджере. Первая комбинация показывает историю каталогов (Alt + Left), вторая позволяет пользователю перейти в родительский каталог (Alt + Up). Они также отображают содержимое каталогов.

~/.zshrc
cdUndoKey() {
  popd
  zle       reset-prompt
  print
  ls
  zle       reset-prompt
}

cdParentKey() {
  pushd ..
  zle      reset-prompt
  print
  ls
  zle       reset-prompt
}

zle -N                 cdParentKey
zle -N                 cdUndoKey
bindkey '^[[1;3A'      cdParentKey
bindkey '^[[1;3D'      cdUndoKey

Заголовок xterm

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

Заголовок xterm задаётся с помощью escape-последовательности OSC \e]2;\a или \e]2;\e\\. Например:

$ print -n '\e]2;Заголовок моего xterm\a'

установит заголовок

Заголовок моего xterm

Простой способ сделать динамический заголовок — менять его с помощью хуков precmd и preexec. Информация о существующих хуках есть в zshmisc(1) § Hook Functions.

С помощью print -P можно также использовать управляющие последовательности Zsh.

Совет:
  • Печать заголовка может быть разделена на несколько команд, если они идут последовательно.
  • GNU Screen посылает заголовок xterm в hardstatus (%h). Если вы хотите использовать string escapes из Screen (например, для цветов), то вам следует установить hardstatus с помощью управляющей последовательности \e_\e\\. В противном случае, если в \e]2;\a будут string escapes, эмулятор терминала получит искажённое название, так как не сможет интерпретировать их.
Примечание:
  • Не используйте опцию -P команды print при печати переменных, чтобы их содержимое не обрабатывалось как управляющие последовательности.
  • Используйте parameter expansion flag q при выводе переменных, чтобы их содержимое не обрабатывалось как управляющие последовательности.
~/.zshrc
autoload -Uz add-zsh-hook

function xterm_title_precmd () {
	print -Pn -- '\e]2;%n@%m %~\a'
	[[ "$TERM" == 'screen'* ]] && print -Pn -- '\e_\005{g}%n\005{-}@\005{m}%m\005{-} \005{B}%~\005{-}\e\\'
}

function xterm_title_preexec () {
	print -Pn -- '\e]2;%n@%m %~ %# ' && print -n -- "${(q)1}\a"
	[[ "$TERM" == 'screen'* ]] && { print -Pn -- '\e_\005{g}%n\005{-}@\005{m}%m\005{-} \005{B}%~\005{-} %# ' && print -n -- "${(q)1}\e\\"; }
}

if [[ "$TERM" == (Eterm*|alacritty*|aterm*|foot*|gnome*|konsole*|kterm*|putty*|rxvt*|screen*|wezterm*|tmux*|xterm*) ]]; then
	add-zsh-hook -Uz precmd xterm_title_precmd
	add-zsh-hook -Uz preexec xterm_title_preexec
fi

Заголовок вкладки в эмуляторе терминала

Некоторые эмуляторы терминалов и мультиплексоры поддерживают установку заголовка вкладки. Используемые escape-последовательности зависят от терминала:

Терминал Escape-последовательности Описание
GNU Screen \ek\e\\ Заголовок окна Screen (%t).
Konsole \e]30;\a Заголовок вкладки Konsole.

Определение окружения

Репозиторий с информацией о том, как определить окружение, в котором работает командная оболочка, в частности: оболочка входа, сеанс Xorg, TTY, сеанс SSH.

Эквивалент /dev/tcp: ztcp

Используйте модуль zsh/net/tcp:

$ zmodload zsh/net/tcp

Он позволяет устанавливать TCP-соединения:

$ ztcp example.com 80

Подробнее: zshmodules(1) § THE_ZSH/NET/TCP_MODULE и zshtcpsys(1).

Сочетание клавиш для выхода из оболочки при введённой команде

По умолчанию Ctrl+d не завершает работу оболочки, если в ней что-то введено. Можно исправить это так:

.zshrc
exit_zsh() { exit }
zle -N exit_zsh
bindkey '^D' exit_zsh

Обработка неизвестных команд с использованием pacman -F

pacman позволяет найти пакет по имени файла, так что можно создать обработчик неизвестных команд, который ищет пакеты, в которых присутствует введённая команда:

~/.zshrc
...
function command_not_found_handler {
    local purple='\e[1;35m' bright='\e[0;1m' green='\e[1;32m' reset='\e[0m'
    printf 'zsh: command not found: %s\n' "$1"
    local entries=(
        ${(f)"$(/usr/bin/pacman -F --machinereadable -- "/usr/bin/$1")"}
    )
    if (( ${#entries[@]} ))
    then
        printf "${bright}$1${reset} may be found in the following packages:\n"
        local pkg
        for entry in "${entries[@]}"
        do
            # (repo package version file)
            local fields=(
                ${(0)entry}
            )
            if [[ "$pkg" != "${fields[2]}" ]]
            then
                printf "${purple}%s/${bright}%s ${green}%s${reset}\n" "${fields[1]}" "${fields[2]}" "${fields[3]}"
            fi
            printf '    /%s\n' "${fields[4]}"
            pkg="${fields[2]}"
        done
    fi
    return 127
}
...
Примечание: База данных файлов в pacman отделена от обычной базы данных синхронизации, и её нужно получать и периодически обновлять командой pacman -Fy. Смотрите pacman (Русский)#Поиск пакета по названию файла.

Вариант, использующий pkgfile: #Обработка неизвестных команд с использованием pkgfile.

Очистка буфера сочетанием клавиш

По умолчанию в большинстве эмуляторов терминала сочетание клавиш, очищающее экран, не очищает backbuffer (ту часть текста, до которой нужно прокрутить вверх, чтобы увидеть её). Решить это можно так:

~/.zshrc
...
function clear-screen-and-scrollback() {
    echoti civis >"$TTY"
    printf '%b' '\e[H\e[2J' >"$TTY"
    zle .reset-prompt
    zle -R
    printf '%b' '\e[3J' >"$TTY"
    echoti cnorm >"$TTY"
}

zle -N clear-screen-and-scrollback
bindkey '^L' clear-screen-and-scrollback
...

Сторонние расширения

Фреймворки настроек

Примечание: Фреймворки добавляют дополнительный уровень абстракции и сложности. Они могут добавлять (и часто добавляют) неопределённое поведение. В случае проблем с оболочкой первым шагом отладки должен быть возврат к чистой оболочке без расширений.
  • oh-my-posh (пакет oh-my-poshAUR) - Движок приглашений для любой оболочки, позволяющий настроить строку приглашения с помощью функции или переменной.
  • oh-my-zsh управляемый сообществом, популярный фреймворк для настройки вашего Zsh. Он поставляется в комплекте с тонной полезных функций, помощников, плагинов, тем.
  • Prezto - мгновенно прекрасный Zsh (доступен в prezto-gitAUR) настроенный фреймворк Zsh. Он поставляется с модулями, разумно расширяющих среду интерфейса командной строки (по умолчанию), псевдонимами (алиасами), функциями, атодополнением, и темами Prompt.
  • ZIM (пакет zsh-zim-gitAUR) - Фреймворк настроек с молниеносной скоростью и модульными расширениями. Zim очень легко настраивается, имеет богатый набор модулей и возможностей без ущерба для скорости и функциональности.

Менеджеры плагинов

  • Antidote (пакет zsh-antidoteAUR) - Полнофункциональная Zsh-реализация старого менеджера плагинов Antibody.
  • zinit (ранее «zplugin», пакет zinit-gitAUR) - Гибкий менеджер плагинов Zsh с чистым fpath, отчётами, управлением автодополнением, турбо-режимом REVIVED.
  • sheldon (пакет sheldon) - Быстрый, настраиваемый менеджер плагинов оболочки, написанный на Rust.
  • Antigen (дступен в antigen-gitAUR) - менеджер плагинов для zsh, вдохновлённый oh-my-zsh и vundle.
  • zgen (пакет zgen-gitAUR) - Лёгкий и простой менеджер плагинов для Zsh. Заброшен.
  • zplug (пакет zplugAUR) - Менеджер плагинов нового поколения для Zsh. Заброшен.

Подсветка синтаксиса как в Fish

Fish обеспечивает очень мощную подсветку синтаксиса. Для использования в zsh, вы можете установить zsh-syntax-highlighting из официального репозитория и обязательно добавьте в ваш ~/.zshrc строку:

source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

Также можно добавить zsh-autosuggestions:

~/.zshrc
source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh

Обработка неизвестных команд с использованием pkgfile

В утилиту pkgfile входит Zsh скрипт, содержащий функцию command_not_found_handler. При вводе неизвестной команды функция автоматически осуществляет поиск в официальных репозиториях.

Для её включения добавьте:

~/.zshrc
source /usr/share/doc/pkgfile/command-not-found.zsh
Примечание: Чтобы это сработало, базу данных pkgfile нужно синхронизировать.

Вариант, использующий pacman: #Обработка неизвестных команд с использованием pacman -F.

Смотрите также

Рекомендуем обязательно обратится к следующим Русскоязычным статьям, для более полного и лучшего понимания.

Статьи на Английском: