LXF132:ZSH

Материал из Linuxformat.

Перейти к: навигация, поиск

Содержание

Zsh обустройте свою оболочку

Одев гидрокостюм и отправившись в морские глубины, Коэн Вервлоесем враз осознал всю важность удобной оболочки.

Многие пользователи никогда не меняют оболочку, установленную по умолчанию в их дистрибутиве Linux, и почти всегда этой оболочкой является Bash (сокращение от Bourne-again shell). Это неплохо, если вы не используете расширенные возможности, но если вы много работаете с командной строкой, не помешает присмотреться и к другим оболочкам, а не только потреблять что дают. Оболочка – важное звено между вами и вашей операционной системой. Если она правильно настроена, ваша работа станет удобнее, эффективнее и производительнее.

В данной статье речь пойдет о Zsh (Z shell) – оболочке, обладающей многими преимуществами Bash и других оболочек, а так же массой возможностей сверх того. После прочтения этой статьи вы получите представление о мощи Zsh и сможете принять информированное решение о том, стоит ли переключаться на нее со стандартной оболочки, предлагаемой вашим дистрибутивом. Основное внимание мы уделим интерактивному использованию Zsh, в меньшей степени – неинтерактивным сценариям, то есть сконцентрируемся на ежедневной работе, а не на скриптописании и автоматизации.

Удобной возможностью многих оболочек является подстановка [globbing], известная также как генерация имен файлов. Широко известный пример – ввод имени *.txt, которое подразумевает все файлы, заканчивающиеся расширением .txt. Ваша оболочка превратит это в список всех таких файлов и передаст его команде – как, например, в ls *.txt.

В Bash возможности подстановки довольно ограничены. Например, как быть, если вы хотите перечислить все файлы с расширением .txt в подкаталогах текущего каталога? Конечно, можно написать ls */*.txt, но тогда выведутся .txt-файлы только с данного уровня вложенности каталогов. Zsh имеет мощное решение по рекурсивному поиску файлов: ls **/*.txt. Эта команда выведет все .txt-файлы во всех подкаталогах. Оцените мощь этого решения: оно почти что делает команду find избыточной. Например, вместо find . -name *.txt | grep foo, Zsh позволяет использовать куда более простую команду: grep foo **/*.txt. Если вы хотите, чтобы Zsh отслеживала символьные ссылки, можно воспользоваться конструкцией ***/; но остерегайтесь бесконечных циклов.

Помимо этого, Zsh воспринимает конструкцию […], подбирающую соответствие любым символам, заключенным в скобки. Например, конструкция *.[cho] обозначает все файлы, в расширения которых входят символы с, h или o. Конструкциям [^…] и [!...] Zsh ставит в соответствие все символы, кроме заключенных в скобках.

Стартовые файлы

Каждая оболочка имеет ряд файлов, используемых ею при запуске для самонастройки. Файлы настройки Zsh, действующие в масштабах всей системы, находятся в каталоге /etc/ (в Ubuntu и ряде других аналогичных дистрибутивов – в /etc/zsh/), а настройки для конкретных пользователей располагаются в их домашних каталогах. При запуске Zsh оболочка считывает следующие файлы в таком порядке:

  • /etc/zshenv и ~/.zshenv
  • если оболочка запускается при входе пользователя в систему: /etc/zprofile и ~/.zprofile
  • если это интерактивная оболочка: /etc/zshrc и ~/.zshrc
  • если оболочка запускается при входе пользователя в систему: /etc/zlogin и ~/.zlogin

А когда пользователь покидает оболочку, запускающуюся при входе в систему [login shell], Zsh читает файлы /etc/zlogout и ~/.zlogout.

Работая с командами, которые записываются в каждый из файлов настройки, важно различать типы оболочек. Регистрационная оболочка [login shell] – это экземпляр оболочки, запускаемый при входе пользователя в систему: например, через SSH или на виртуальном терминале.

Интерактивная оболочка отображает для пользователя приглашение к вводу команд – например, если вы в Ubuntu открываете окно Терминал [Terminal]. Однако если вы запустите команду ssh host some-command, то это будет регистрационная оболочка, а не интерактивная.

Зэтимология

Первую версию Zsh написал Пол Фолстад [Paul Falstad], будучи студентом Принстонского университета. Когда он искал имя для своей оболочки, его взгляд упал на входное имя преподавателя-ассистента, Zhong Shao: zsh.

Использование квалификаторов

Квалификаторы подстановки [glob qualifiers] – еще одно приятное дополнение Zsh: эта оболочка умеет выбирать типы файлов по использованию определенных флагов в скобках в конце подстановочного шаблона. Например, чтобы перечислить только каталоги, вложенные в текущий, можно воспользоваться командой:

print *(/)

Для обозначения только обычных файлов пользуйтесь конструкцией (.); для каталогов – (/), исполняемых файлов – (*), символьных ссылок – (@), сокетов – (=), именованных каналов – (p), файлов устройств – (%), блочных файлов – (%b) и символьных файлов – (%с).

Точно так же можно проверять права доступа к файлам: (r), (w) и (x) означают файлы, допускающие чтение, запись и выполнение своим владельцем. Сокращения (R), (W) и (X) выбирают файлы со «всемирными» правами доступа [world permissions], а конструкции (A), (I) и (E) задают групповые права. Например, чтобы найти все исполняемые файлы в текущем дереве каталогов, скомандуйте

ls **/*(.x)

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

print *(f:gu+rw,o-rwx:)
Скорая помощь

Сменить на Zsh оболочку по умолчанию можно командой chsh -s /usr/bin/zsh. Изменение войдет в силу только после выхода из системы.

Еще один полезный подстановочный квалификатор проверяет, является ли пользователь или группа владельцами файла. Чтобы протестировать собственного пользователя или группу, используйте конструкции (U) или (G), соответственно. Для остальных пользователей и групп нужно добавлять идентификатор (ID) пользователя или группы к конструкциям (u) или (g). Так, (u0) по зволит вам искать все файлы, принадлежащие root, а (u1001) – все файлы, принадлежащие пользователю с user ID, равным 1001. При желании можно использовать и имена, но их надо заключать между символами двоеточия: например, (u:koan:) выбирает файлы, принадлежащие пользователю koan.

Zsh может выбирать файлы по времени модификации или доступа – для этого используются конструкции (m) и (a), соответственно. Искать можно по точному времени или по периодам: до (-) или после (+) конкретного момента. По умолчанию используются дни, но время можно измерять и в месяцах (m), неделях (w), часах (h), минутах (m) или секундах (s).

Например, вот команда, находящая все файлы, к которым вы обращались за последнюю неделю:

print **/*(.aw-1)

Следующая команда найдет все файлы, модифицированные за последний час:

print **/(.m0)

Квалификаторы подстановки по размеру файла работают аналогично: (L) указывает размер файла, по умолчанию измеряемый в байтах. Помимо байтов, размер файла можно измерять в килобайтах (k), мегабайтах (m), или в блоках по 512 байт (p). Таким образом можно очень быстро найти в текущем каталоге все файлы, размер которых превышает 1 мегабайт:

print *(Lm+1)

Списки завершения можно «расцветить» яркимикрасками.

Квалификаторы подстановки можно произвольным образом комбинировать. Получаемые конструкции могут показаться громоздкими, но при знании основных квалификаторов их толкование не составит труда. Например, *(u0WLk+10m0) означает «файлы, принадлежащие пользователю root, к которым все имеют доступ с правом записи; размер их больше 10 КБ; модифицировались в течение последнего часа». Перед квалификатором можно использовать символ ^, который означает его отрицание; а запятая служит оператором ИЛИ – or. На man-странице приведена более подробная информация обо всех квалификаторах подстановки, включая методы сортировки вывода.

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

Определить псевдоним очень просто. Например, если вы часто вводите команду ls -lh, можно создать псевдоним lh с помощью следующей команды:

alias lh=”ls -lh”

Псевдонимы удобны для пользователей; для интерактивных оболочек задавайте их в файле zshrc. Если после определения псевдонима ввести lh, оболочка преобразует ваш ввод в ls -lh. Это изменение будет действовать и при указании для lh аргументов и опций, например: lh -a foodir/.

Глобальные псевдонимы

А если вам хочется создать псевдонимы для команд, не являющихся первым словом в командной строке? Zsh заботится и об этом: такие псевдонимы называются глобальными. Для создания глобального псевдонима укажите в команде alias опцию -g, например:

alias -g L=”|less”

Теперь вам будет очень удобно листать страницы вывода другой команды, просто добавив к ней псевдоним L – например, dmesg L.

Вот еще несколько полезных глобальных псевдонимов:

alias -g ...=’../..’
alias -g ….=’../../..’
alias -g …..=’../../../..’

Еще один вариант псевдонимов – суффиксы. Вот несколько поучительных примеров:

alias -s tex=vim
alias -s pdf=xpdf
alias -s html=w3m

Это означает, что если мы введем имя файла, как если бы это была команда, то файл с расширением .tex будет открыт редактором Vim, файл с расширением .pdf – с помощью xpdf, а файл с расширением .html – с помощью w3m.

Псевдонимы можно создавать и для каталогов, хотя команда alias для этого не годится. Часть таких псевдонимов в оболочке уже определена: это, например, ~ для вашего домашнего каталога и ~user – для домашнего каталога пользователя user. Зато командой hash можно задавать собственные имена для произвольных каталогов, например:

hash -d down=~/Desktop/Downloads

Теперь вы сможете перейти в этот каталог из любого другого места файловой системы, введя команду cd ~down.

Еще одна опция, упрощающая работу с каталогами, хоть и не являющаяся псевдонимом – это AUTO_CD. Если в вашем файле zshrc вы установите эту опцию командой setopt AUTO_CD, а потом введете с клавиатуры нечто, не имеющее аргументов и не являющееся командой, Zsh проверит, не является ли введенный вами текст именем каталога. Например, если вы введете Documents, Zsh поведет себя так, как если бы вы ввели команду cd Documents. Переход в родительский каталог тоже упростится: вместо cd .. достаточно будет ввести ...

Большинство оболочек автоматически завершают имена файлов по нажатию клавиши Tab. В Bash вы можете расширить эту опцию до дополнения имен хостов и т. д., установив пакет bash-completion. Zsh также имеет мощную и полностью программируемую систему дополнений, но по умолчанию она не активирована.

Для ее подключения установите в своем файле zshrc такие опции:

autoload -U compinit
compinit

Когда система автодополнения Zsh будет активирована, попробуйте набрать несколько типичных Linux-команд, но вместо ввода аргументов нажмите клавишу Tab. Вы наглядно убедитесь в мощи Zsh и увидите, что она может добавлять. Например, у Zsh хватает интеллекта для того, чтобы дополнять команду cd каталогами. Еще один пример – введите команду tar -xvzf и нажмите клавишу Tab. Zsh отобразит имена файлов в текущем каталоге, имеющих расширение .tar.gz. Если вы введете tar -xvf, Zsh отобразит только имена .tar-файлов. Вы можете даже избирательно извлекать конкретные файлы из архива .tar.gz, не вводя полный путь.

Привыкнув к системе дополнений, вы обнаружите, что практически перестали печатать такие команды, как cd, ls и тому подобные, чтобы определить, где вы находитесь и какие файлы там имеются. Вы начнете печатать свои команды, а система дополнения сама найдет для вас нужные файлы. Это относится не только к файлам, но и к переменным оболочки, именам пользователя, следующим за опцией -user и именам хостов, и даже к именам пользователя в SSH. Более того, система работает даже с файлами удаленной учетной записи, при условии, что применяются SCP и сервер с публичными ключами.

Большинству пользователей незачем изменять стандартную систему завершений в Zsh – она и так достаточно интеллектуальна. Однако при желании вы можете расширить ее, введя собственные правила завершения или изменив стандартные. Давайте рассмотрим эту возможность на примере SSH. По умолчанию, система дополняет имена всех локальных пользователей и все имена хостов, перечисленные в .ssh/known_hosts. Но если вам нужно регистрироваться на двух машинах, лучше задать собственное правило завершения, например:

zstyle ‘:completion:*’ users-hosts koan@vervloesem.eu kvervloe@discovery.example.org

Это правило удобно тем, что если вы введете с клавиатуры koan и нажмете клавишу Tab, Zsh уже будет знать, что имя хоста должно быть vervloesem.eu, потому что имени другого хоста соответствует другое имя пользователя.

В список автозавершения можно добавить различные цвета, как показано на иллюстрации. Мы будем использовать те же цвета, которые отображает ls от GNU с опцией --color:

zmodload -I zsh/complist
zstyle ‘:completion:*’ list-colors ${(s.:.)LS_COLORS}

Здесь предполагается, что LS_COLORS установлена как переменная окружения. Если в вашем дистрибутиве это не так, запустите команду dircolors и скопируйте ее вывод в ваш файл zshrc, вставив его перед только что приведенными строками.

Скорая помощь

Если вы определили именованные каталоги, можете установить опцию CDABLEVARS: она позволит вам использовать команду cd down вместо cd ~down или (в комбинации с AUTO_CD) даже просто down.

Приглашения оболочки

Приглашение оболочки – это, скорее всего, первая вещь, которую вам захочется настроить. Опытные пользователи видят приглашение командной строки тысячи раз в день, и логично подумать о приятности данного зрелища. К счастью, Zsh справляется с этой задачей блестяще. Приглашение командной строки управляется переменной PROMPT.

Например, стандартное приглашение Zsh выглядит так: “ %m %#”. Это значит, что в строке приглашения отображается короткое имя хоста, за которым следует значок % (для обычных пользователей) или # (для root).

Еще одна уникальная черта Zsh – поддержка правостороннего приглашения, управляемого переменной RPROMPT, с тем же синтаксисом, что и PROMPT. Это удобно, если вам не нравится левостороннее приглашение, изменяющееся по длине. Например, чтобы показать имя текущего каталога, достаточно установить “ %~” в качестве правостороннего приглашения. Zsh справляется и с длинными правосторонними приглашениями. Например, пусть ваш текущий каталог имеет длинный путь; как только ввод команды приблизится к правостороннему приглашению, оно исчезнет. Для приглашений можно определить условные подстроки. Это удобно, если вам хочется, чтобы часть приглашения зависела от результата выражения. Например, вот как настроить Zsh, чтобы при успешном выполнении последней команды в приглашении отображался символ O, а в случае неудачи – X:

PROMPT=”%(?.O.X)”

Переменные приглашения Zsh

  • %/ Текущий рабочий каталог
  • %~ Краткое обозначение текущего рабочего каталога (например, ~ для домашнего, но сокращениям подвергаются и именованные каталоги)
  • %t Время в 12-часовом формате
  • %T Время в 24-часовом формате
  • %* Время в 24-часовом формате с секундами
  • %n Имя пользователя
  • %m Сокращенное имя хоста
  • %M Полное имя хоста
  • %# % для обычных пользователей и # – для root
  • %? Статус последней команды (0 – успешное выполнение)

Добавим цвета

Монохромное приглашение выглядит уныло, а его текст сливается с выводом ваших команд. Если использовать выделение цветом, то на экран будет не просто приятнее смотреть, но и вывод станет выглядеть более структурированным. Использовать выделение цветом в приглашении можно с помощью управляющих последовательностей [escape sequences].

Скорая помощь

Zsh имеет даже программу по проверке орфографии. Если вы активируете ее командой setopt CORRECT в вашем файле zshrc, оболочка будет обнаруживать ошибки (например, chomd) и просить вас их исправить.

В состав Zsh входит функция colors. Когда она загружена и выполняется, она определяет ассоциативные массивы $fg и $bg, используя соответствующие управляющие последовательности для выбранных цветов. Например, ${fg[red]$bg[yellow]} создает управляющие последовательности для отображения красного текста на желтом фоне. Следует помнить, что управляющие последовательности, которые не перемещают курсор, всегда должны открываться символами ' %{' , а замыкаться – ' %}' .

Чтобы загрузить эти цвета, добавьте в ваш файл zshrc следующие строки:

autoload colors zsh/terminfo
if [[ “$terminfo[colors]” -ge 8 ]]; then
	 colors
fi

Теперь вернемся к нашему условному выражению с O и X. Мы можем добавить туда выделение цветом. Если последняя команда завершилась успешно, нужно отобразить зеленый символ O, в противном случае – красный X:

PROMPT=”%(?.%{${fg[green]%}O. %{${fg[red]%}X) %{${fg[default]}%}

Zsh позволяет автоматически запускать определенный код при определенных обстоятельствах. Для этого нужно только реализовать некоторые специальные функции. Две наиболее часто используемые – chpwd() и precmd(). Zsh вызывает chpwd() при каждом изменении текущего каталога, а precmd() выполняется перед тем, как Zsh отобразит новое приглашение. Обе функции регулярно используются для отображения текущего каталога в строке заголовка эмулятора терминала. Если, помимо оболочки, вы применяете другие программы, изменяющие строку заголовка эмулятора терминала (например, Vim), воспользуйтесь precmd() – после отработки другой программы она восстановит строку заголовка. Отображение текущего каталога в строке заголовка делается так (адаптировано с man-страницы):

precmd () {
	  -t 1  || return
	 case $TERM in
		 (sun-cmd) print -Pn “\e]l%~\e\\”
		 ;;
		 (*xterm*|rxvt(dt|k|E)term) print -Pn “\e]2;%~\a”
		 ;;
	 esac
}

Существует еще одна функция, periodic(), которая исполняется периодически, по истечении количества секунд, установленного в переменной PERIOD.

Есть удобная утилита time, которая показывает общее время CPU, использованное командой. Единственная проблема – не позабыть ввести time перед запуском команды. А что если вы запускаете весьма долгоиграющую команду и хотите определить продолжительность ее выполнения? В Zsh вы можете сделать это, задав в переменной REPORTTIME срок в секундах. Если команда превысит его, оболочка выведет информацию о времени выполнения по ее завершении. Формат выводимых сведений указывается в переменной TIMEFMT. Например:

REPORTTIME=5
TIMEFMT=”%U user %S system %P cpu %*Es total”

Emacs среди оболочек

Вам должно быть уже ясно, что изучение Zsh – штука непростая. Зато Zsh и даст вам очень много, если не пожалеть времени на постижение основ. К счастью, есть множество отличных ресурсов, посвященных этой оболочке. Прежде всего это подробная система man-страниц. Кроме того, имеется онлайн-руководство Питера Стефенсона [Peter Stephenson] (доступное на http://zsh.sourceforge.net/Guide/zshguide.html). Оно немного устарело, но сохраняет свою ценность. Еще один ресурс для любителей Zshhttp://zshwiki.org. Итак, приступайте к настройке Zsh – вы очень выиграете, получив улучшенную оболочку.

Протестируйте темы командой prompt и упростите интерпретацию вывода с помощью встроенных функций Zsh по управлению цветами.

Темы приглашения

Zsh поставляется с набором тем оформления приглашения, очень простых в установке. Инициализируйте их:

autoload -U promptinit
promptinit

После этого вы сможете пользоваться командой prompt для выбора тем. Команда prompt -p обеспечит предпросмотр тем, а команда prompt -s themename назначит тему themename в качестве текущей. Если вам хочется выбирать тему случайным образом, скомандуйте prompt -s random.

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию