Zsh: установка и настройка

Алексей Федорчук
2001-2002 г

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

Содержание

Приступаем к установке

Оболочка zsh стандартно входит в большинство (я бы сказал — во все из мне известных) полнофункциональных дистрибутивов Linux, в качестве портов и пакетов доступна во Free- и OpenBSD (на счет NetBSD — просто не помню), портирована даже в AtheOS (вернее — ее отпрыска Syllable). Так что проблем с ее получением быть не должно. Устанавливаем zsh штатным для данного дистрибутива методом и переходим к следующему разделу.

Если же почему-либо zsh в составе дистрибутива не обнаружился — отправляемся на ftp://ftp.zsh.org/pub/ или какое-либо его зеркало. И качаем в свое удовольствие исходники последней стабильной версии, или, при желании, разрабатываемой — различий в стабильности между ними я не заметил.

Исходники zsh распаковываются и собираются обычным образом — ./configure, make, make install, никаких неожиданностей здесь не предвидится. Единственно, я предварительно, чисто для интереса, поинтересовался бы опциями конфигурирования —

$ ./configure --help

Из которых не побрезговал бы опцией --bindir=/bin — это будет полезно, если zsh будет использоваться как login shell.

В дистрибутивах Linux, предусматривающих автоматическое обновление общесистемных профильных файлов (например, в Gentoo), может возникнуть необходимость в том, чтобы zsh брал свои переменные окружения из какого-либо общего конфига, например, /etc/profile. Для этого при начальном конфигурировании исходников следует указать

$ ./configure --enable-zprofile=/etc/profile

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

Теперь же, установив zsh тем или иным образом, делаем его своей пользовательским шеллом по умолчанию — login shell (одной из команд типа usermod, pw, chsh) и —

Начинаем настройку

Без этого нам, скорее всего, не обойтись. В свежеустановленном zsh мы имеем шанс не увидеть почти ничего из описанных выше прелестей — ни развертывания сокращений путей, ни автодополнений опций и аргументов, ни выразительных приглашений командной строки. Перед нами будет безликая строка с именем машины (типа localhost%), которая едва-то будет справляться с обычным автодополнением команд и путей (и то — не обязательно). Могут возникнуть проблемы даже с вызовом собственной экранной документации man zsh. Почему?

Дело в том, что zsh имеет очень богатый набор собственных конфигурационных файлов, о которых я скажу чуть ниже. Но при установке его эти файлы не помещаются автоматически ни в каталог /etc, ни в домашний каталог пользователя — то есть ни в одно из тех мест, где их можно было бы ожидать. Конечно, совсем без первичных настроек zsh не останется: он прекрасно воспринимает их из таких общесистемных профильных файлов, как /etc/profile, /etc/login и т.д. Однако, во-первых, для этого он должен быть собран должным образом. А во-вторых, и вести себя при этом он будет почти точно также, как и соответствующие оболочки (bash или tcsh, а то и /bin/sh — почему, например, во FreeBSD zsh по первости не способен даже к автодополнению команд). От одного из этих профильных файлов zsh унаследует и переменные окружения, включая MANPATH — почему подчас не сможет найти и свою собственную документацию.

Так что для придания zsh полного блеска следует прибегнуть к его собственным конфигурационным файлам. Правда, сначала придется отыскать их примеры из штатной поставки — должен заметить, что в разных системах они могут обнаружиться в весьма неожиданных местах. Так, во FreeBSD их штатное место — каталог /usr/local/share/examples/zsh, в дистрибутиве Gentoo Linux примеры оказываются в /usr/share/doc/zsh-XXX-rX/StartupFiles, в иных — вполне могут оказаться где-нибудь в районе /usr/share/zsh, и т.д.

Для минимизации времени на поиски выдам секрет — примеры конфигурационных файлов zsh, входящие в штатный комплект, называются — zlogin, zshenv и zshrc (возможно, с расширением .gz), и благодаря моей доброте :-) их не трудно будет отыскать командой find — за пределы каталога /usr файлы эти попасть не должны (даже в том случае, если, как в Gentoo, сам исполняемый файл zsh оказывается в каталоге /bin).

После изыска конфигов для сердца вольного есть два пути. Первый — простой, копируем их в наш домашний каталог в качестве dot-файлов (~/.zlogin, ~/.zshenv и ~/.zshrc, соответственно), после чего наслаждаемся жизнью. В ряде случаев этого достаточно, чтобы получить доступ к базовым (но очень даже расширенным, сравнительно с собратьями) возможностям этого шелла.

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

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

Первый шаг на этом пути — задаться вопросом, а зачем zsh‘у так много конфигов, если другие шеллы спокойно обходятся двумя (а то и одним, как /bin/sh). На это я отвечу, что конфигов в zsh вовсе не много, а очень много: в дополнение к трем примерным в разделе FILES его man-страницы можно найти упоминание еще о zprofile и zlogout (и, соответственно, ~/.zprofile и ~/.zlogout). А в ходе пользования им вы, скорее всего, увидите в своем каталоге еще и такие файлы, как ~/.zcompdump и ~/.zhistory.

Так для чего нам такое богачество? Чтобы разобраться в этом, вспомним о трех видах функционирования любого шелла — неинтерактивном, интерактивном и подвиде последнего — главном пользовательском (login shell). Так вот, файл /etc/zshenv (или ~/.zshenv) считывается при каждом запуске любого экземпляра zsh, независимо от того, происходит он интерактивно или опосредованно. Настройки файла /etc/zshrc~/.zshrc) имеют силу для любого интерактивного запуска zsh. И, наконец, файлы /etc/zlogin и /etc/zprofile оба вместе (как и соответствующая им пара ~/.zlogin и ~/.zprofile) относятся только к тому экземпляру интерактивно запущенного zsh, который выступает в качестве login shell.

Зачем так сложно? А для того, чтобы можно было гибко (и индивидуально) настроить неинтерактивные, интерактивные и пользовательские экземпляры шеллов. Действительно, очевидно, что на настройку неинтерактивного шелла влияет только содержимое файла /etc/zshenv~/.zshenv), на настройку любого интерактивно запущенного экземпляра — уже он же вкупе с /etc/zshrc~/.zshrc), тогда как поведение login shell определяется кумулятивным эффектом всех трех (или даже четырех) их пар.

Хорошо, но зачем же нам два конфига для login shell? — спросите вы меня. Ответ прост — из соображений совместимости с bash и tcsh. Для пояснения чего вернемся к истории вопроса. В первозданном шелле Борна существовал только один конфиг — /etc/profile (~/.profile) для любых экземпляров шелла. В bash к нему прибавился еще и файл /etc/bashrc (~/.bashrc) для интерактивного использования (считываемые, естественно, после предыдущего — как более молодой по происхождению).

В csh же набор конфигов был совсем иной. Там изначально существовали два конфига — /etc/csh.env (~/.csh.env) на все случаи жизни и /etc/login (~/.login) — в качестве конфигуратора login shell, считываемые именно в таком порядке.

В zsh же, дабы удовлетворить привычки пользователей любых предшествовавших шеллов, были включены оба «логируемых» конфига, причем порядок их считывания был унаследован от каждого из родителей. В результате получилась довольно сложная последовательность при запуске login shell:

zshenv -> zprofile -> zshrc -> zlogin

Причем каждый конфиг сначала, естественно, считывается из каталога /etc, а затем из домашнего каталога пользователя берется его аналог. Разумеется, если все четыре файла присутствуют (и там, и там). Что, сразу скажем, отнюдь не обязательно. Очевидно, что совместное использование zprofile и zlogin ни малейшего смысла не имеет. Просто бывшим пользователям bash привычней первая схема запуска login shell, бывшим приверженцам tcsh — вторая. Забегая вперед, замечу, что вообще пользователь может обойтись только одним конфигом в своем домашнем каталоге (например, ~/.zshrc для любого интерактивного экземпляра шелла — ведь login shell также будет интерактивным), а все общие настройки получать из общесистемного конфига (например, /etc/profile). Более того, в дистрибутиве Gentoo Linux именно так поступить лучше всего — к причинам вернусь позднее.

Осталось объяснить смысл остальных dot-файлов из пользовательского каталога. Каковой, впрочем, ясен из названий: ~/.zlogout — это сценарий, отрабатываем при выходе из login shell, ~/.zhistory хранит историю команд (это и есть ее буфер), а ~/.zcompdump (насколько я понимаю) — делает то же самое, но для встроенных функций zsh. Два последних файла возникают (при выполнении некоторых условий) сами собой, и речи о них больше почти не будет.

Разобравшись с назначением dot-файлов, можно, наконец, выполнить

Собственно конфигурирование

Процесс этот начнем с того, что отделим зерна от плевел, то есть решим: а какие же именно файлы нужно настроить. Для начала я оставил бы в покое все файлы из каталога /etc — вернее, просто не стал бы копировать туда примеры. Почему? Да потому, что во многих дистрибутивах Linux имеются либо предварительно настроенные общесистемные конфиги, либо предусмотрены средства для их автоматического создания и обновления (ниже я продемонстрирую это на примере Gentoo). А во FreeBSD в каталоге /etc принято хранить только профильные файлы общесистемного шелла (сиречь /bin/sh, тогда как настройка пользовательского шелла — сугубо личное дело пользователя.

Так что ограничиваемся только нашим домашним каталогом. Однако и здесь многое зависит от ОС и дистрибутива. Так, в user-ориентированных дистрибутивах Linux первый кандидат на удаление (или не-копирование) — файл ~/.zshenv. Конечно, его можно создать в предельно облегченном виде (например, настройка приемов неинтерактивной работы здесь абсолютно лишняя). Характерно, что в штатном примере zshenv присутствует только переменная PATH. Но ведь ее можно получить из общесистемного /etc/profile, не так ли?

Особенно лишним выглядит ~/.zshenv для пользователей Gentoo. Как можно прочитать в соответствующей документации, здесь существует прекрасный механизм установки общесистемных переменных — env-update, автоматически обновляющий главный профильный конфиг /etc/profile. Так что при отсутствии ~/.zshenv все необходимое (в актуальном виде) будет браться оттуда. В присутствии же его — zsh откажется от считывания /etc/profile, в результате чего такие переменные, как локаль, EDITOR, PAGER и т.д., придется определять дополнительно.

А вот во FreeBSD и тех дистрибутивах Linux, которые (как, например, CRUX и Archlinux) не имеют средств автоматизации установки общесистемных переменных, файл ~/.zshenv оказывается практически необходимым. И ниже я попытаюсь обосновать это (а заодно и продемонстрировать, что в нем может содержаться).

Далее, решаем, а нужен ли нам отдельный конфиг для login shell, и если нужен — то какой из них — ~/.zlogin или ~/.zprofile. Теоретически, можно обойтись и без того, и без другого. Уж без последнего — так наверняка, не зря же его нет ни среди штатных примеров, ни среди многочисленных конфигов, которыми поделились с народом активные пользователи zsh (см. источники информации). А файл ~/.zlogin у меня, например, есть, хотя содержание его может варьировать от системы к системе.

Не помешает и файл ~/.zlogout — его возможное содержание также будет рассмотрено позднее.

Остается главный (по крайней мере, самый большой) конфиг — ~/.zshrc. Что с ним делать? Это легко уяснить, ознакомившись со штатным примером.

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

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

Начнем с последнего, то есть приглашения командной строки. В этом качестве могут использоваться:

  • полное или сокращенное имя хост-машины (последнее принято по умолчанию для первичного);
  • путь к текущему каталогу в различных формах;
  • номер текущей команды в буфере истории или строки в данном сеансе работы;
  • имя пользователя, или командной оболочки;
  • номер текущего терминала;
  • дата и время в разных форматах;
  • индикация работы от лица суперпользователя);
  • любые символы типа стрелок, крышечек, скобочек;
  • текстовые сообщения (например, поздравление с началом трудового процесса);
  • многое другое (подробности — в man zshhmisc).

Плюс к этому приглашения могут быть оформлены визуально различно: выделением жирным шрифтом (boldface mode) или повышенной яркостью (underline mode), инвертированием текста/фона (standout mode), а также цветами. Все это позволяет добиться максимальной информативности приглашения и его внешней выразительности.

Из опций настройки интерактивности — вспомним о том, что обеспечивает расширенные возможности автодополнения. А обеспечиваются они строками, следующими после комментария:

# Setup new style completion system. To see examples of the old style (compctl

# based) programmable completion, check Misc/compctl-examples in the zsh

# distribution.

и имеющими вид

autoload -U compinit

compinit

Вообще, штатный пример файла zshrc очень неплохо прокомментирован — по аглицки, но разобраться можно:-).

Далее — опции управления историей команд. Здесь для начала следует определить файл, в котором эта история будет храниться (в примере по умолчанию таковой отсутствует, и никакая история по умолчанию не сохраняется по выходе из сеанса zsh):

HISTFILE=~/.zhistory

Теперь — объем нашей исторической памяти, задаваемый двумя опциями —

HISTSIZE=1000

определяющей память текущего сеанса, и

SAVEHIST=1000

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

Для обеспечивая наращивания файла истории после каждого сеанса работы (в пределах установленной квоты) определяем:

setopt APPEND_HISTORY

Объем исторической памяти можно установить любым, однако не стоит расходовать его на повторение дублирующихся команд, ошибочными нажатиями Enter в пустой строке и т.д.:

setopt HIST_IGNORE_ALL_DUPS

setopt HIST_IGNORE_SPACE

setopt HIST_REDUCE_BLANKS

Можно настроить и еще много чего, но на этом пока закончим (некоторые опции будут подробнее рассмотрены в следующем разделе). Потому что наступило время подумать, а что представляют из себя установленные нами опции (типа compinit и т.д.)? А представляют они собой по преимуществу встроенные функции из комплекта zsh, которые в изобилии можно обнаружить в каталоге /usr/share/zsh/4.0.6/functions. И именно благодаря этим функциям и удается все настроить.

А еще — становится понятным, почему иногда zsh в пакетных дистрибутивах, устанавливаясь из бинарников, ведет себя не вполне подобающим образом. Да именно потому, что комплект функций в поставке и их использование в файлах примеров не вполне идентичны (по крайней мере, мне такие случаи встречались). При сборке же из исходников с сайта проекта, насколько мне довелось наблюдать, идентичность эта гарантирована. Тот же результат, естественно, достигается и в Source Based дистрибутивах (или, скажем, в системе портов FreeBSD).

Вообще говоря, я долго не мог понять, почему пользователи не любят zsh. И в конце концов пришел к выводу — именно потому, что сборщики дистрибутивов подчас не умеют его готовить. Это — не только мое мнение: многие пользователи пакетных дистрибутивов свидетельствуют, что установленный из «коробки» zsh в их системах работает весьма криво. Так что позволю себе привести

Личный рецепт приготовления

Как-то на одном форуме промелькнул вопрос — а как сделать, чтобы в командной строке zsh клавиши типа Delete, End, Home вели себя нормально (по умолчанию они этого делать не собираются). У меня до этого долго не доходили руки — я в этих целях привык к клавишным комбинациям (см. следующий раздел). Однако некоторое чувство дискомфорта преследовало: как же так, какой-то там bash умеет нормально обращаться с клавишами, а любимый zsh — не умеет. А тут и случай представился: во время затеянной в рамках мегатестирования тотальной пересборки Qt/KDE/иже_с_ними времени образовалось — вагон и маленькая тележка. И я наконец-то разобрался с клавишами в zsh. О чем с удовольствием рапортую в этом разделе.

Из многочисленных zsh-конфигов я (в настоящее время) использую: ~/.zshenv, считываемый при каждом запуске экземпляра оболочки (интерактивном и неинтерактивном), ~/.zshrc, считываемый при каждом интерактивном ее запуске, и ~/.zlogin, считываемый при каждом запуске zsh в качестве login shell. При этом установка переменных окружения происходит в стиле C-Shell: сначала из ~/.zshenv, затем из ~/.zshrc и, наконец, из ~/.zlogin.

Так что первым в моей схеме идёт ~/.zshenv. Он оказывает воздействие только при shell-скриптинге. Поэтому у меня он очень мал. В Linux-варианте (для Archlinux) он выглядит так:


#

# My ~/.zshenv for Linux

#export PATH="/bin:/usr/bin:

/usr/local/bin:/usr/X11R6/bin:

/opt/bin:/opt/kde/bin"

Во FreeBSD все примерно то же, но, естественно, /opt в PATH включать не требуется:

#

# My ~/. zshenv for FreeBSD

#

PATH="/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin"

QTDIR=/usr/local/qt

PATH="$PATH:$QTDIR"

MANPATH="$QTDIR/doc/man:$MANPATH"

LD_LIBRARY_PATH="$QTDIR/lib:$LD_LIBRARY_PATH"

export QTDIR PATH MANPATH LD_LIBRARY_PATH

Понятно, что оба файла можно записать поизящней (с точки зрения формы), но — так уж они исторически склались.

Основное внимание я уделяю файлу ~/.zshrc, так как им определяется поведение zsh не только при авторизации в консоли, но и при запуске терминальных окон в Иксах.


#

# My ~/.zshrc

#

# Path для поиска командой cd: то есть вместо cd $HOME/docs/editors/

# можно набирать просто cd editors

cdpath=(~/media ~/docs)## Установка нормального поведения клавиш Delete, Home, End и т.д.:

case $TERM in

 linux)

 bindkey "^[[2~" yank

 bindkey "^[[3~" delete-char

 bindkey "^[[5~" up-line-or-history

 bindkey "^[[6~" down-line-or-history

 bindkey "^[[1~" beginning-of-line

 bindkey "^[[4~" end-of-line

 bindkey "^[e" expand-cmd-path ## C-e for expanding path of typed command

 bindkey "^[[A" up-line-or-search ## up arrow for back-history-search

 bindkey "^[[B" down-line-or-search ## down arrow for fwd-history-search

 bindkey " " magic-space ## do history expansion on space

 ;;

 *xterm*|rxvt|(dt|k|E)term)

 bindkey "^[[2~" yank

 bindkey "^[[3~" delete-char

 bindkey "^[[5~" up-line-or-history

 bindkey "^[[6~" down-line-or-history

 bindkey "^[[7~" beginning-of-line

 bindkey "^[[8~" end-of-line

 bindkey "^[e" expand-cmd-path ## C-e for expanding path of typed command

 bindkey "^[[A" up-line-or-search ## up arrow for back-history-search

 bindkey "^[[B" down-line-or-search ## down arrow for fwd-history-search

 bindkey " " magic-space ## do history expansion on space

 ;;

esac

# Примечание: если, скажем, в KDE для konsole

# выбрать тип Linux console, необходимости

# во второй секции нет. Консоль Linux в KDE можно

спокойно установить и во FreeBSD.

# К слову сказать, совсем уж нормального

# поведения клавиш в syscons я до сих пор

# не добился:-(

# Use hard limits, except for a smaller stack and no core dumps

unlimit

limit stack 8192

limit core 0

limit -s

# Установка атрибутов доступа для

# вновь создаваемых файлов

umask 022

# Исправление поведения less - для ликвидации

# лишних Esc и прочего безобразия при

# выводе man-страниц.

# Насколько мне известно, нужно только в некоторых

# дистрибутивах Linux

export LESS="-R"

# Установка alias'ов

## alias'ы для команд, не требующих коррекции, но требующих подтверждения

alias mv='nocorrect mv -i'

# переименование-перемещение c пogтвepжgeнueм

alias cp='nocorrect cp -iR'

# рекурсивное копирование с подтверждением

alias rm='nocorrect rm -i'

# удаление с подтверждением

alias rmf='nocorrect rm -f'

# принудительное удаление

alias rmrf='nocorrect rm -fR'

# принудительное рекурсивное удаление

alias mkdir='nocorrect mkdir'

# создание каталогов без коррекции

## Примечание: если не определить здесь nocorrect,

## zsh будет настойчиво предлагать подстановку

## существующих имен при создании каталогов,

## копировании и т.д.

## Разные полезные (ИМХО) alias'ы

alias h=history

alias grep=egrep

### вывод свободного дискового пространства

### в мегабайтах

alias df='df -m'

### Представление вывода less в more-подобном виде

### (с именем файла и процентом вывода)

alias less='less -M'

### Русский словарь для ispell по умолчанию

alias ispell='ispell -d russian'

## aliases для команды ls<  ### показ классификации файлов в цвете и ### символически (Linux) alias ls='ls -F --color=auto' ### Во FreeBSD достаточно alias ls='ls -F'  ### вывog в gлuннoм фopмaтe alias ll='ls -l'  ### вывog всех файлов, включая dot-фaйлы, кромe . u .. alias la='ls -A'  ### вывog вcex фaйлoв в gлuннoм фopмaтe, вkлючaя inodes alias li='ls -ial'  ### вывод только каталогов alias lsd='ls -ld *(-/DN)'  ### вывog тoльko dot-фaйлoв alias lsa='ls -ld .*'  # Установка глобальных псевдонимов # для командных конвейеров alias -g M='|more' alias -g L='|less' alias -g H='|head' alias -g T='|tail' alias -g N='2>/dev/null'

# Ниже даны опции, относящиеся к функциям zsh,

# которыми собственно и определяется мощь этой оболочки

# Shell functions

setenv() { typeset -x "${1}${1:+=}${(@)argv[2,$#]}" }

# csh compatibility

freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done }

# Where to look for autoloaded function definitions

fpath=($fpath ~/.zfunc)

# Autoload all shell functions from all directories in $fpath (following

# symlinks) that have the executable bit on (the executable bit is not

# necessary, but gives you an easy way to stop the autoloading of a

# particular shell function). $fpath should not be empty for this to work.

for func in $^fpath/*(N-.x:t); autoload $func

# automatically remove duplicates from these arrays

typeset -U path cdpath fpath manpath

# Указание путей к man-страницам.

## Linux:

manpath="/usr/man:/usr/share/man:

/usr/local/man:/usr/X11R6/man:/opt/qt/doc"

## FreeBSD:

manpath="/usr/share/man:/usr/local/man:/usr/X11R6/man"

export MANPATH

# Список хостов, к которым будет применяться

# автодополнение при наборе в командной строке

# например, как аргументов браузера или

# ftp-клиента (see later zstyle)

hosts=('hostname' ftp.freebsd.org ftp.archlinux.org)

# Установка вида приглашения

## Обычное приглашение вида ~%=>

## (каталог от домашнего - пользователь/root - стрелка)

PROMPT='%~%#=> '

## Приглашения для второй линии многострочных команд

## вида #_строки>

PROMPT2='%i%U> '

## Приглашение с правой стороны экрана вида

## 19:15 vc/5 (время - номер консоли)

RPROMPT=' %T %y%b'

# Всякие переменные

## файл истории команд

## если не указан, история не будет сохраняться

## при выходе из сеанса

HISTFILE=~/.zhistory

## Число команд, сохраняемых в HISTFILE

SAVEHIST=5000

## Чucлo кoмaнд, coxpaняeмыx в сеансе

HISTSIZE=5000

## Примечание:

## рекомендуются равные значения для

## SAVEHIST и HISTSIZE

DIRSTACKSIZE=20

# Опции истории команд

## Дополнение файла истрии

setopt  APPEND_HISTORY

## Игнopupoвaть вce пoвтopeнuя команд

setopt  HIST_IGNORE_ALL_DUPS

## Игнopupoвaть лишние пpoбeлы

setopt  HIST_IGNORE_SPACE

## Удалять из файл истории пустые строки

setopt  HIST_REDUCE_BLANKS

# Установка-снятие опций шелла

setopt   notify globdots correct pushdtohome cdablevars autolist

setopt   correctall autocd recexact longlistjobs

setopt   autoresume histignoredups pushdsilent noclobber

setopt   autopushd pushdminus extendedglob rcquotes mailwarning

unsetopt bgnice autoparamslash

## Отключение звукового сигнала

## при ошибках

setopt  No_Beep

## Нe cчuтaть Control+C зa выxog uз oбoлoчku

setopt  IGNORE_EOF

# Autoload zsh modules when they are referenced

zmodload -a zsh/stat stat

zmodload -a zsh/zpty zpty

zmodload -a zsh/zprof zprof

zmodload -ap zsh/mapfile mapfile

# Опции общего поведения

# bindkey -v # режим навигации в стиле vi

bindkey -e # peжuм нaвuгaцuu в cтuлe emacs

bindkey ' ' magic-space    # also do history expansion on space

bindkey '^I' complete-word # complete on tab, leave expansion to _expand

# Для разворота сокращенного ввода типа cd d/e в docs/editors

autoload -U compinit

compinit

# Completion Styles

# list of completers to use

zstyle ':completion:*::::' completer _expand _complete _ignored _approximate

# allow one error for every three characters typed in approximate completer

zstyle -e ':completion:*:approximate:*' max-errors

'reply=( $(( ($#PREFIX+$#SUFFIX)/3 )) numeric )'

# insert all expansions for expand completer

zstyle ':completion:*:expand:*' tag-order all-expansions

# formacodeing and messages

zstyle ':completion:*' verbose yes

zstyle ':completion:*:descriptions' format '%B%d%b'

zstyle ':completion:*:messages' format '%d'

zstyle ':completion:*:warnings' format 'No matches for: %d'

zstyle ':completion:*:corrections' format '%B%d (errors: %e)%b'

zstyle ':completion:*' group-name ''

# match uppercase from lowercase

zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'

# offer indexes before parameters in subscripts

zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters

# command for process lists, the local web server details and host completion

#zstyle ':completion:*:processes' command 'ps -o pid,s,nice,stime,args'

#zstyle ':completion:*:urls' local 'www' '/var/www/htdocs' 'public_html'

zstyle '*' hosts $hosts

# Filename suffixes to ignore during completion (except after rm command)

zstyle ':completion:*:*:(^rm):*:*files' ignored-pacodeerns '*?.o' '*?.c~'

'*?.old' '*?.pro'

# the same for old style completion

#fignore=(.o .c~ .old .pro)

# ignore completion functions (until the _ignored completer)

zstyle ':completion:*:functions' ignored-pacodeerns '_*'

# Флаги оптимизации для gcc

CFLAGS="-O3 -march=pentium4 -fomit-frame-pointer

-funroll-loops -pipe -mfpmath=sse -mmmx -msse2 -fPIC"

CXXFLAGS="$CFLAGS"

BOOTSTRAPCFLAGS="$CFLAGS"

export CFLAGS CXXFLAGS BOOTSTRAPCFLAGS

И, наконец, файл ~/.zlogin. Что осталось неохваченным в ~/.zshrc и требуется только при авторизации в системе? Правильно, пользовательские переменные для определения терминала, редактора, пейджера и т.д.

#

# My ~/.zlogin for FreeBSD

#

from 2>/dev/null

EDITOR=joe

PAGER=less

TERM=${TERM:-cons25r}

export EDITOR PAGER TERM

Кроме того, в Linux’е здесь же резонно установить locale (во FreeBSD локаль лучше определять через класс пользователя). И потому для Linux — дополнение:


#

# My ~/.zlogin appendix for Linux

#

# Установка всех локально-зависимых переменных,

# кроме LC_ALL

export LANG="ru_RU.koi8r"# Установка десятичной точки

# вместо запятой

# (требуется для некоторых счетных программ)

export LC_NUMERIC="POSIX"

Да, самое последнее — файл ~/.zlogout, отрабатываемый по завершении сеанса пользовательского шелла. У меня от включает две строчки

sync

clear

назначение которых более чем понятно (синхронизация дисковых кэшей и очистка экрана).

Это мои пользовательские конфиги. Почти те же самые я использую и для root’а, с минимальными коррективами. Так, переменная path в /root/.zshenv дополняется значениями

/sbin:/usr/sbin:/usr/local/sbin

В /root/.zshrc опция cdpath имеет вид

cdpath=(/etc /usr)

Кроме того, во FreeBSD здесь я исключаю переменные CFLAGS, CXXFLAGS и BOOTSTRAPCFLAGS, так как от лица root’а все собирается через систему портов, где их аналоги определяются в файле /etc/make.conf.

А в /root/.zlogin локаль (в Linux) установлена как

export LANG="POSIX"

так как некоторые программы упорно не желают собираться при какой-либо иной.

Заключительные замечания

Я уже упоминал, что проект zsh прекрасно документирован, один User’s Guide чего стоит. Однако внимание прессы, как онлайновой, так и бумажной, к нему явно недостаточно. И потому из дополнительных источников информации на ум приходит только (если не считать отрывочных упоминаний в паре книжек по Linux) статья Мэтта Чапмена (Macode Chapman) — Curtains up: introducing the Z shell. Да еще недавно появился на русском языке материал Алексея Отта Командный процессор Zsh

Много полезного можно узнать из анализа dot-файлов различных пользователей, ссылки на которые отыскиваются как на www.zsh.org, так и в иных местах. Собирать все эти ссылки мне было лениво (да подчас я и не помню, где их отыскал), так что все свои находки я собрал воедино в виде отдельного тарбалла.