На данный момент существует довольно много различных командных оболочек: классические sh (Шелл Борна), bash (Born again shell), экзотические scsh, pyshell и герой нашего сегодняшнего обзора — zsh.

ZSH

Итак, zsh (или Z-shell) — оболочка первоначально разрабатывавшаяся Паулем Фальстадом (Paul Falstad), начиная с 1990 года. Сейчас Z-shell развивается в рамках самостоятельного проекта сообществом энтузиастов (Zsh Development Group) и является полностью свободной программой.

Существует мнение, что в zsh нашли свое воплощение все прогрессивные тенденции таких развитых оболочек, как bash и tcsh. И, ознакомившись с его возможностями, с этим трудно не согласиться — в zsh есть все, что было в других оболочках, причём реализовано на очень высоком уровне.

Какими особенностями определяется в первую очередь удобство работы в командной оболочке? В порядке, котором с ними сталкивается пользователь, это будут:

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

Автодополнением команд, частично введенных в ответ на приглашение оболочки, трудно удивить пользователей bash или tcsh. Обычно оно работает довольно прямолинейно, если есть безальтернативный вариант, то оболочка автоматически подставляет именно его, если же команд несколько, то показывается список возможных команд. Однако zsh идет дальше — и после вывода списка возможных команд, в ответ на последующие нажатия таба начинает их перебор, а при необходимых настройках может выводить различной сложности «меню», которые облегчают навигацию по всем возможным вариантам автодополнения. То же самое работает и для дополнения путей к файлам, а так же для прочих аргументов и опций команд.

Одной из самых интересных и полезных функций которые предоставляет пользователю zsh развертывание путей при сокращенном их наборе. Так, чтобы просмотреть содержимое каталога /Users/Sergey/Desktop/, в командной строке достаточно набрать ls /Us/Se/Des и нажать клавишу табуляции: сокращенный ввод пути (разумеется, при безальтернативности оного) будет автоматически развернут до полного ls /Users/Sergey/Desktop/. Если для пути есть какие то вариации, то в каждом случае можно так же с помощью таба выбрать точный вариант. Так же этот функционал хорошо работает с другой особенностью — переход в нужную директорию без необходимости набора команды cd. Так что бы перейти в директорию /Users/Sergey/Desktop/ мы так же набираем /Us/Se/Des, нажимаем tab, а затем enter и вот мы оказываемя в нужной нам директории.

В zsh, так же как и в остальных шелах, имеется возможность устанавливать алиасы (псевдонимы) для команд, что значительно сокращает количество нажатий на клавиши. Но, так же как и в случае остальных ускорителей производительности, zsh пошел дальше и добавил в свой функционал такое понятие как global aliases. Смысл его в том, что если нам необходимо просмотреть вывод той же команды l (которая является alias’ом для более длинной команды ls -la), но при помощи less, то мы можем не писать каждый раз l | less, а создать глобальный алиас alias -g L=’| less’ и потом просто добавлять его к нужным нам командам будь это l -g L или же cat README -g L.

Ещё одной замечательной возможностью является полностью настраиваемая строка приглашения (promt). В ней можно сделать практически все что угодно для достижения максимального удобства использования, будь то показ времени, пути, названия директории или даже такие специфически фичи, как статус git репозитория в текущей папке.

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

Oh my! ZSH!

Хотя zsh и позволяет настраивать себя почти полностью, но это не всегда необходимо, особенно если есть такие вещи как OhMyZsh.

Как мы можем увидеть в описании проекта на github:

A community-driven framework for managing your zsh configuration. Includes 40+ optional plugins (rails, git, OSX, hub, capistrano, brew, ant, macports, etc), over 80 terminal themes to spice up your morning, and an auto-update tool so that makes it easy to keep up with the latest updates from the community.

В общем-то, как оно не парадоксально, но так и есть. Большое число плагинов и тем, все необходимые настройки из коробки. Так что, если у вас MacOS или если у вас уже был до этого установлен zsh, смело выполняйте команду


curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sh

дожидайтесь установки и перезапускайте терминал. Вуаля! У нас есть настроенный и полностью работающий zsh. Почти полностью настроенный. Несколько операций над ним всё-таки надо произвести для достижения нужного уровня комфорта.

Первым делом открываем настройки, которые лежат в домашней папке нашего пользователя (я использую для редактирования vim):


vim ~/.zshrc

Что мы видим в этом файле? Установленную по умолчанию тему robbyrussell и включенный плагин git и в общем-то всё. Соответственно начать можно как раз таки с выбора темы (полный список доступных тем можно посмотреть на соответствующей wiki странице проекта), а так же выбора необходимых нам плагинов (список доступных плагинов). Соответственно нашему выбору изменяем необходимые строчки в .zshrc. В моем случае это ZSH_THEME=”agnoster” и plugins=(git symfony2). Из плагинов стоит отметить плагин для Ruby on Rails, а так же плагин для автодополнения Symfony2 консоли.

И напоследок несколько полезных опций которые можно добавить в .zshrc и которые упрощают жизнь.

  • HISTSIZE=100 — количество команд хранимых в истории
  • SAVEHIST=100 — количество команд сохраняемых в файл истории
  • HISTFILE=~/.zsh/history — путь к файлу истории
  • setopt append_history — говорит о том, что данные истории выполнения команд будут добавляться к файлу истории, вместо того, что бы перезаписывать его каждый раз. Команды добавляются в порядке завершения сессий.
  • setopt inc_append_history — работает почти так же, как append_history, за тем лишь отличием, что команды добавляются к файлу истории сразу же, а не ждут окончания работы шела.
  • setopt extended_history — сохраняет кроме всего длительность и время начала выполнения команды
  • setopt hist_find_no_dups — когда ищем по истории, то не показываем дупликаты команд
  • setopt hist_reduce_blanks — Удаляем лищние пробелы при добавлении в файл истории
  • setopt hist_ignore_space — Удаляем из истории все команды которые начинаются с пробела и соответственно пустые строки
  • setopt hist_no_store — не сохраняем в историю команду вызова истории history(fc-l)
  • setopt hist_save_no_dups — при дублировании команды в истории, сохраняем информацию только о более новом вызове.
  • unsetopt correct_all — единственная вещь которая меня очень раздражает в zsh это то, что он постоянно пытается поправить то, что ему кажется неправильным, например bn (в моем случае это alias для git checkout -b) на bin. Конечно можно прописывать каждое исключение из этого правила отдельно, но я решил поступить кардинально и полностью отключил данное поведение zsh (unsetopt correct_all), за ненадобностью.

Теперь осталось перенести старые настройки из bashrc (например $PATH) ииии… Космический корабль готов к покорению галактики!

З.Ы.: Так же советую посмотреть эпизод Rails Casts, в котором рассказывается о zsh, там освещено несколько интересных моментов.