Воззрения кота Manual’а. CLI и Zsh. Часть 2. Zsh в Cintu

Алексей Федорчук

manul-logo-100

Ближайшие страницы посвящены приёмам работы к командной строке вообще и в Zsh в особенности. Именно эта командная оболочка принята в Cintu как регистрационная (login shell) по умолчанию, вместо традиционного для почти всех дистрибутивов Linux оболочки Bash.

Zsh и мифы о нём

Вокруг командной оболочки Zsh линуксоидами создано не намного меньше легенд и мифов, чем древнеримскими греками — вокруг Троянской войны. И столь же тесно мифы эти и легенды сопряжены с типичной подменой понятий, когда тёплое смешивается с мягким, а интерактивное со скриптовым. Ибо, как «Илиада» описывает один из эпизодов осады города Илиона (который настолько не совсем Троя, что совсем даже не она), так и от прочтения всяких сетевых материалов про Zsh складывается впечатление, что говорят о какой-то другой оболочке, вовсе не той, с которой её применители имеют дело изо дня в день.

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

По возможностям zsh больше всего похож на ksh.

Это — первый миф. Потому что Zsh похож на Ksh не более, чем Bash, Ash или Dash. А, как все перечисленные оболочки, с ним совместим. И было бы странно, если бы было иначе: всё это — оболочки, совместимые со стандартом POSIX Shell, при разработке которого за основу был принят именно шелл Корна.

И, раз уж зашла речь о совместимости. Бытует мнение, что Zsh отягощён совместимостью с Csh и Tcsh. Однако тягот тут нет ни малейших. Просто те, кто привык к синтаксису C Shell’а, могут использовать его в своих пользовательских конфигах и скриптах. А могут — не использовать, никто не неволит их это делать. Подобно тому, как обладательниц прокладок (не помню каких) вовсе не заставляют прыгать с парашютом или нырять с аквалангом.

Второй миф как раз и касается скриптов: якобы Zsh не подходит для их сочинения. С этим трудно спорить: для этого он подходит не больше, чем ГТТ — для гонки по автострадам. Потому что как тот, так и другой создавались для совершенно других целей: ГТТ — для езды в отсутствии дорог вообще, Zsh — для интерактивной работы в CLI.

И тут надо заметить, что Bash изначально тоже задумывался как оболочка для интерактивной работы. Хотя в «чистом» виде её возможности в этом плане достаточно ограничены: значительная часть интерактивного функционала Bash’а обеспечивается дополнительными пакетами readline и bash-comletion. Правда, в большинстве дистрибутивов они устанавливаются вместе с Bash автоматически. Однако, во-первых, это бывает не всегда. А во-вторых, даже с ними в интерактивном режиме возможности Bash по сравнению с Zsh выглядят как джип супротив ГТТ — в тундре.

Что же до скриптинга — для Zsh сочинять скрипты, конечно, не возбраняется, однако — для работы в пределах одной отдельно взятой машины (или серии машин в руках одного хозяина). В произвольной машине Zsh может или отсутствовать как класс, или быть настроен несколько иначе, и последнее иногда отражается на выполнении сценариев оболочки (вплоть до их невыполнения). С чем связан ещё один миф — что Bash для целей скриптинга подходит больше.

Но тут всё дело в том, что действительно Bash на произвольной Linux-машине, скорее всего, будет — и, скорее всего, настроенным «из коробки» примерно одинаково (то есть почти никак). Однако это не является каким-то достоинством самой оболочки, а только данью традиции. И имеются в природе дистрибутивы Linux’а, которые этой традиции не следуют (например, Tiny Core Linux, в котором роль системной командной оболочки исполняет Ash). А уж ожидать встретить Bash установленным в произвольной BSD-системе было бы вообще опрометчиво.

Так что на самом деле единственный по настоящему универсальный инструмент для скриптинга — эвентуальный POSIX Shell, обычно представляющийся как /bin/sh. Практическими же его воплощениями являются Ash и его Debian-модификация Dash. Именно такой подход последовательно провидится в дистрибутивах семейства Ubuntu: в них системные сценарии из каталога /etc/ содержат такой ша-банг:

#!/bin/sh

А /bin/sh является символической ссылкой на исполняемый файл Dash, в чём легко убедиться командой

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 фев 17  2016 /bin/sh -> dash*

Ша-банг /bin/bash в Ubuntu’идах можно встретить только в конфигах программ, не относящихся к «коренным» пакетам системы. Впрочем, насколько я знаю, такое же положение имеет место быть в Debian’е и его «чистых» клонах.

Ещё один распространённый миф — что Zsh это улучшенная версия Bash, контаминированная с возможностями Csh. Однако если обратиться к истории, становится ясно, что в 1990 году, когда Пауль Фальстад (Paul Falstad) сочинял первую версию Zsh, Bash’у от роду едва стукнул годик, и заимствовать из него было ещё нечего. А вот из оболочки TENEX C Shell, обладавшей тогда самыми развитыми интерактивными возможностями, заимствовано было многое. Так что Zsh скорее можно считать результатом адаптации Tcsh на предмет совместимости с POSIX Shell. Хотя совместимость с конфигами Csh/Tcsh была сохранена «из уважения к памяти предков», и сохраняется до сих пор.

И последний миф, на котором мы остановимся — о какой-то сверхъестественной сложности конфигурирования Zsh по сравнению с Bash, который якобы «правильно» настроен «из коробки». Во-первых, изначальная настроенность последнего, мягко говоря, несколько преувеличена — по умолчанию она не предусматривает даже такой банальной операции, как рекурсивное копирование (без опции -r).

Во-вторых, при первом запуске Zsh как login shell предлагается запустить сценарий автоматического конфигурирования этой оболочки, завершающийся созданием файла ~/.zshrc, который будет включать все необходимые данному применителю опции.

И в-третьих, эффективное применение Zsh вовсе не требует каких-то страшных конфигов в сотни (а то и тысячи) строк, отыскивания их в сети или, тем более, пребывания завсегдатаем сайта Oh My ZSH! — хотя всё это и не вредно. На самом деле достаточно знать об основных уникальных фичах этой оболочки в интерактивном режиме, таких, как глобальные псевдонимы, расширенное и множественное перенаправление, расширенное автодополнение etc. А уж если ощутить в них потребность — то включить соответствующие опции в своём личном конфиге будет делом несложной техники.

А отказаться от интерактивных функций Zsh после их освоения будет психологически невозможным. Во всяком случае, мы не знаем ни одного применителя этой оболочки, который не испытывал бы дрожи при одной мысли, что враги народа заставят его работать в Bash’е.

Именно поэтому командная оболочка Zsh была принята в системе Cintu как пользовательская регистрационная (login shell) по умолчанию. А, дабы её можно было эффективно использовать «из коробки», она сопровождается здесь конфигурационным файлом ~/.zshrc. В нём задействована изрядная часть полезных интерактивных функций Zsh, в том числе и интеграция с менеджером пакетов apt. Что, конечно, не запрещает применение этого конфига в любом другом дистрибутиве семейства Ubuntu. А, за вычетом строк, специфических для deb based систем — и в любой UNIX-подобной системе вообще.

Zsh в Cintu

Вкратце резюмируем причины, по которым Zsh принят в Cintu как регистрационная оболочка пользователя по умолчанию для того аккаунта, который создаётся при инсталляции системы:

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

Не все из перечисленных возможностей работает в Zsh «из коробки» — большая их часть требует соответствующей настройки. В Cintu включён главный конфигурационный файл этой оболочки ~/.zshrc для пользователя, чей аккаунт создаётся при установке системы. В него включены все опции, необходимые для работы описываемого функционала. Файл этот по возможности прокомментирован на русском языке. А поскольку консоль в Cintu корректно русифицирована, его можно прочитать даже при крахе графической оболочки.

Оболочка Zsh в Cintu по умолчанию устанавливается как login shell также для каждого вновь создаваемого аккаунта, и наследует аналогичный конфиг из /etc/skel/.zshrc.

Те из потенциальных применителей Cintu, которые категорически не пожелают расставаться с привычным Bash’ем, могут легко вернуть его в качестве регистрационной оболочки текущего пользователя командой

$ chsh -s /bin/bash

Однако мы с котом Manual’ом надеемся, что потенциальные применители Cintu оценят несравненные достоинства Zsh как интерактивной оболочки. И необходимости выполнять эту процедуру у них не возникнет.

Заниматься настройкой Zsh применителю Cintu сразу также не потребуется: здесь эта оболочка сконфигурирована так, чтобы были доступны основные убойные фичи были доступны «из коробки». И закомством с ними мы сейчас и займёмся. А в Части 3 будет рассказано, как получить их в более иных дистрибутивах.

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

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

Для повторения последней введённой команды служит удвоенный символ восклицательного знака — !!. Например, команда

$ ls /usr/share/fonts

выведет содержимое указанного каталога:

cmap/  fira-mono/  fira-sans/  Input-Font/ …

Если же теперь ввести

$ !!

и нажать Enter, мгновенно последует тот же самый вывод:

ls /usr/share/fonts
cmap/  fira-mono/  fira-sans/  Input-Font/

Символ !! может быть использован как аргумент другой команды — в этом случае на его место будет подставлена предыдущая команда. Например, если по забывчивости попытаться установить какой-либо пакет от имени обычного пользователя командой

$ apt install apt-file

последует сообщение об ошибке такого содержания:

E: Не удалось открыть файл блокировки /var/lib/dpkg/lock - open (13: Отказано в доступе)
E: Не удалось выполнить блокировку управляющего каталога (/var/lib/dpkg/); у вас есть права суперпользователя?

Очевидно, что для установки пакета требуются привилегии администратора, которые в данной ситуации резонно разово получить командой sudo. А чтобы не вводить вручную предыдущую конструкцию, её можно подменить !!:

$ sudo !!
sudo apt install apt-file
[sudo] пароль для alv:

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

$ ls /usr/share/fonts

сразу же набрать в просто ls последовательно клавишу Escape и клавишу с символом точки ., то в командной строке появится тот же путь, что и ранее. Причём перед отправкой команды на исполнение его можно отредактировать, например, дописав в него следующий по вложенности подкаталог:

$ ls /usr/share/fonts/Input-Font/

По исполнении этой команды первое после набора ls нажатие Escape+. вызовет предыдущий аргумент, второе — предпоследний, то есть /usr/share/fonts, и так далее. Однако тут надо быть внимательным: комбинации Escape+. до лампочки, к какой команде она подставляет аргументы, и со временем в строке окажется что-то совсем не подходящее, например:

$ ls apt-file

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

Автоматическое дополнение

Во всех развитых шеллах с давних времён (хотя и не изначально) существует механизм автоматического дополнения команд и путей к файлам по нажатию клавиши табулятора. Механизм этот прекрасно известен всем линуксоидам по его реализации в Bash’е. Однако в Zsh обычное автоматическое дополнение можно дополнить парой полезных фич — и в Cintu в пользовательском ~/.zshrc это сделано «из коробки».

Первая из них — развёртывание аббревиатур путей в пути полные. То есть если набрать в командной строке что-то вроде

$ ls /u/s/f/I

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

$ ls /usr/share/fonts/Input-Font/

Вторая Zsh-специфичная особенность автодополнения — вывод предлагаемых вариантов в виде меню-подобного списка. А именно, если после набора последовательности символов

$ ls /u/s/f/I

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

cli-i-zsh_022

И так — до получения «окончательного результата»:

cli-i-zsh_023

Обе эти фичи не берутся не берутся с неба, а достигаются включением соответствующих опций в ~/.zshrc. Каких именно — будет рассказано в Части 3. А пока перейдём к вопросам истории (команд).

Вопросы истории (команд)

Извлечение ранее введённых команд из их «истории» — ещё один, наряду с подстановками и автоматическим дополнением, способ минимизации набора символов при работе в CLI. И эта возможность также существует по всех современных командных оболочках. Однако и тут Zsh некогда выделился дополнительными функциями (правда, ныне реализованными и в Bash, хотя там они включаются несколько иным способом).

Для начала — несколько общих слов. Всем известно, что команды в истории оных можно последовательно просматривать, нажимая клавиши Up (назад) и Dowm (вперёд). А найдя там нужную — отправить её на исполнение нажатием клавиши Enter. При необходимости предварительно отредактировав опции и (или) аргументы. Однако это может быть занятием достаточно нудным, потому что нужно учитывать следующее.

История команд, доступная для «перебора клавишами», сохраняется в Zsh как бы дважды. Во-первых, в буфере текущего сеанса шелла, запущенного в данном терминальном окне, его вкладке (если эмулятор терминала таковые поддерживает) или в текущей виртуальной консоли (впрочем, о специфике CLI в «голой» консоли речь будет отдельная).

А во-вторых, история команд записывается в специальный dot-файл домашнего каталога пользователя — в Cintu таковым является ~/.zhistfile. Причём в ней Zsh настроен таким образом, что вновь введённая команда попадает в файл истории сразу, а не по завершении текущего сеанса. То есть она будет последней в списке команд следующего сеанса, при открытии нового терминального окна или вкладки в существующем.

Так что при высоком лимите на количество строк в буфере сеанса и в файле истории (а в Cintu лимит этот — 2000 и 10000 строк, соответственно), перебор команд может потребовать немало времени. Конечно, файл ~/.zhistfile можно просто просмотреть, например, командой less, дабы найти нужную, в том числе и с применением фильтра типа grep. Однако и это не намного легче. Даже с учётом того, что в файл истории, в соответствие с принятыми в Cintu настройками Zsh, не попадают дубликаты команд и пустые строки.

Кстати, пока не забыл: предотвратить попадание команды в историю, если это почему-либо не желательно (например, её аргумент содержит учётные данные доступа ftp-серверу), можно, введя пробел перед именем команды. Однако в буфере текущего сеанса она всё равно сохранится до конца оного, и будет доступна для «перебора» — причём именно в такой, «историко-недоступной», форме.

Думаю, ни для кого не секрет также, что для вызова списка команд предназначена специальная команда history. Однако в данном случае следует учитывать, что это — встроенная команда оболочки, зависит от последней, а потому её возможности в Bash и в Zsh различаются. И редкий случай — не в пользу последней, поскольку в Bash её функционал обеспечивается библиотекой GNU History Library, в Zsh не задействованной.

Впрочем, потеря не велика — команда history в её Bash-модификации никогда не казалась мне очень удобной. Тем более что в Zsh есть замечательный механизм history-substring-search — поиска в истории по начальной последовательности символов.

Что это такое — проще пояснить на примере: вы вводите в командной строке один символ (для примера — s) и нажимаете клавишу Up. И тут в дальнейший «перебор» включаются только те команды из истории, которые с буковки s начинаются. Вводя дополнительные символы, можно сузить круг поиска: например, последовательность sudo позволяет просмотреть, что мы наколбасили от лица суперпользователя.

Кроме того для облегчения процедуры поиска предусмотрена такая интересная возможность, как наращиваемый поиск (incremental search). Выполняется он так: после нажатия (при пустой командной строке) клавишной комбинации Control+R появляется предложение ввести алфавитный символ (или — последовательность символов произвольной длины), заведомо входящий в состав требуемой команды:

$ bck-i-search: _

Ввод такого символа выведет последнюю из команд, его содержащих. При этом введённый символ будет отмечен знаком курсора. Он не обязан входить в имя команды, но может быть составляющим её опций или аргументов (имени файла или пути к нему, например). Следующее нажатие Control+R зафиксирует курсор на предыдущем символе, в пределах этой же или более ранней по списку команды, и т.д. Однако вместо этого в строке поиска можно вводить дополнительные символы, детализирующие условия поиска команды (или — её опций и аргументов).

Процедуру поиска можно продолжать вплоть до достижения требуемого результата — то есть нахождения той команды, которая нужна именно сейчас. Нажатие клавиши Enter в любой из этих моментов запускает найденную (то есть помещённую в командную строку) команду на исполнение, с завершением поиска. Поиск обрывается также и нажатием комбинации Control+C. Перед запуском найденная команда может быть отредактирована стандартными средствами — с использованием управляющих последовательностей.

Перебор через history-substring-search и инкрементный поиск по Control+R отнюдь не исключают друг друга, а дополняют: первым способом проще искать ранее введённые директивы по имени команды, вторым — по её аргументам, например, по имени файла.

И ещё, и инкрементный поиск, и history-substring-search имеется как в Zsh, так и в Bash. И в обоих оболочках первая функция работает по умолчанию, а вторая должна быть включена в конфигурационных файлах, причём по разному. Как это делается в Zsh — мы расскажем в Части 3. А включение этой функции в Bash описано, например, здесь. И справедливости ради стоит заметить, что функция history-substring-search впервые появилась в оболочке Tcsh, где она, как правило, включена по умолчанию.

Псевдонимы обычные, глобальные и «суффиксные»

Псевдонимы для команд с их опциями (alias) — ещё один из простых способов минимизировать ввод командных директив, применяемый во всех оболочках. Способ этот обычно сводится к подмене команды с какой-либо опцией (или их набором) самим именем команды, для которой эта опция (или опции) чаще всего востребованы.

Обычно такие псевдонимы заносятся в пользовательский конфиг регистрационной оболочки, в нашем случае ~/.zshrc. Например, псевжоним

alias mv='mv -i'

предотвращает случайное перезаписывание одноимённых файлов при перемещении или переименовании. А псевдоним

alias cp='cp -iR'

делает то же самое для команды копирования. И, кроме того, обеспечивает рекурсивное копирование содержимого каталогов. Эти псевдонимы будут подробно рассмотрены при описании конфигурационного файла ~/.zshrc.

Однако в Zsh имеется два вида псевдонимов, которые ещё больше облегчают жизнь применителя этой командной оболочки. И, насколько я знаю, не имеющие аналогов в Bash’е и прочих shell’ах

Первый из них — так называемые глобальные псевдонимы (global alias). Всех нас раздражает ситуация, когда в ответ на попытку поиска файла утилитой find или фрагмента текста grep выводится множество сообщений о том, что доступ к некоему каталогу запрещён. Что выглядят примерно так:

find: «/var/cache/ldconfig»: Отказано в доступе

И среди таких сообщений, занимающих иногда многие экраны, полезная информация просто теряется.

Разумеется, каждый, кто систематически работает в CLI, знает, что для подавления этого «шума» достаточно присобачить к конструкции поиска посредством утилиты find или grep маленький аппендикс в виде 2> /dev/null, перенаправляющий все сообщения об ошибках в «нулевой» файл.

Однако в Zsh борьба с «шумом» осуществляется ещё проще: достаточно задать такой глобальный псевдоним:

$ alias -g N='2>/dev/null'

где -g указывает, что следующий символ (или символы) представляют собой не простой псевдоним, а глобальный, N — его имя, а следующая после равенства последовательность в строгих кавычках — подменяемое им выражение. И теперь можно задавать команду поиска файлов вида:

$ find path2 -name [filename] N

и больше не заботиться об отделении «зёрен от плевел».

Глобальные псевдонимы очень полезны в командных конструкциях перенаправления по конвейеру, например, для поэкранного представления длинного вывода какой-либо команды:

$ alias -g L='|less'

А для фильтрации вывода по вхождению последовательности символов можно задать такой глобальный псевдоним:

$ alias -g G='|grep'

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

$ apt search apt G '^apt-'

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

$ alias -g W='|wc -m'

Ибо нашему брату часто требуется прибегать к такой конструкции:

$ cat filename W

Она в данном случае выведет число символов в текстовом файле — что для нас важнее числа байт (а при использовании 16-битной кодировки для преимущественно кириллического текста эти значения не совпадают).

Второй вид уникальных псевдонимов в Zsh — псевдонимы «суффиксные» (более удачного определения их я не придумал). Подобно тому, как добавление к команде alias опции -g превращает обычный псевдоним в глобальный, так и опция -s делает его «суффиксным». То есть привязывает суффикс имени файла (в просторечии часто называемый «расширением») к некоей программе, которая может сотворить над ним нужное действо. Например, если задать псевдоним такого вида

$ alias -s txt='nano'

а затем набрать в командной строке имя указанного текстового файла (при необходимости с указанием пути к нему)

$ path2/filename.txt

то этот самый файл будет открыт в текстовом редакторе Nano.

Это, конечно, банальщина. Но есть и более интересное применение «суффиксных» псевдонимов. Например, с их помощью можно просматривать содержимое пакетов (применительно к нашему случаю — *.deb). Для чего надо задать такой псевдоним:

$ alias -s deb='dpkg-deb -c'

И теперь достаточно набрать в командной строке полное имя deb-файла:

$ path2/hunspell-ru-aot_0.4.0-2_all.deb

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

drwxr-xr-x alv/alv           0 2016-09-19 11:47 ./usr/
drwxr-xr-x alv/alv           0 2016-09-19 11:47 ./usr/share/
drwxr-xr-x alv/alv           0 2016-09-19 17:58 ./usr/share/hunspell/
-rw-r--r-- alv/alv      279246 2016-09-19 11:47 ./usr/share/hunspell/ru_RU.aff
-rw-r--r-- alv/alv     4695673 2016-09-19 11:47 ./usr/share/hunspell/ru_RU.dic
...
lrwxrwxrwx alv/alv           0 2016-09-19 17:44 ./usr/share/myspell/dicts/ru_RU.aff -> /usr/share/hunspell/ru_RU.aff
lrwxrwxrwx alv/alv           0 2016-09-19 17:44 ./usr/share/myspell/dicts/ru_RU.dic -> /usr/share/hunspell/ru_RU.dic

Разумеется, определения всех постоянно используемых псевдонимов, и глобальных, и «суффиксных», также не обязательно задавать каждый раз в командной строке, как в приведённых выше примерах — их резонно занести в файл ~/.zshrc. Что, не можем удержаться от очередного напоминания, и сделано в Cintu, что называется, «искаропки». То есть применителю этой системы, если он не откажется от использования Zsh в качестве login shell, не придётся заморачивать себе голову вводом ни одного из приведённых выше псевдонимов. Как, впрочем, и многих других, которые ему потребуются в жизни: всё учтено могучим ураганом.

Жизнь без команд

Казалось бы, CLI, обеспечиваемый командными оболочками, предназначен для ввода команд. Однако командная оболочка Zsh, вопреки своему названию, позволяет обходиться привычных команд. Не без всех, конечно, а только немногих. Но зато принадлежащих к числу самых употребимых.

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

Очень просто. Вспомним, что переход в некий каталог для этого типа файлов, именуемого, ни что иное, как исполнение для обычного (ordinary) файла. И потому вполне логично, что как для запуска, например, скрипта оболочки не требуется никакой специальной команды, так и для перехода в каталог, к которому данный пользователь имеет доступ (то есть для него этот каталог имеет бит исполнения), ему достаточно указать полный путь к нему, без всяких команд. Например, введя к командной строке что-нибудь вроде

$ /usr/share/fonts/

он немедленно оказывается в каталоге со шрифтами.

«Безкомандный» переход в каталоги распространяется и на «символические» обозначения последних. Так, команда

$ ~

переместит пользователя в его домашний каталог. Как, кстати, и команда, а директива

$ ..

в — каталог, родительский относительно текущего. Если же в командной строке ввести прямой слеш

$ /

то произойдёт перемещение в корень файловой иерархии.

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

$ Download

и даже не обязательно целиком (достаточно Dow и нажать табулятор), то, вне зависимости от текущего положения, пользователь окажется в одноимённом подкаталоге своего домашнего каталога. Или, если он предпочитает локализованные имена, то в каталоге ~/Закачки.

По умолчанию такой «беспутёвый» способ перехода работает только для стандартных подкаталогов домашнего каталога пользователя (таких, как ~/Pictures, ~/Documwents и так далее). Однако, как будет показано в очерке о настройках Zsh, никто не запрещает распространить его на другие часто посещаемые каталоги.

И кстати: как известно, для определения текущего положения в файловой иерархии предназначена специальная команда pwd. Однако в Zsh и без неё можно обойтись с помощью настройки приглашения командной строки, о чём тоже будет говориться в соответствующем очерке.

Ещё одна из часто используемых команд CLI — less,относимая к семейству так называемых пейджеров (не путать с тем, чем лохи в песочницах ковыряются). То есть программ поэкранного просмотра файлов (преимущественно текстовых), в число которых входят также ветхозаветная утилита more и некогда пропагандируемая в качестве прогрессивной программа most.

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

$ < ~/.zshrc

выведет на экран содержимое своего главного конфига. Которое, как и при выводе через, например less, можно пролистывать поэкранно клавишами PgDown и PgUp, просматривать построчно стрелками Down и Up, отыскивать нужные последовательности символов с помощью /что_надо, повторять поиск вперёд или назад с помощью клавиш n и N, соответственно.

Однако это ещё не всё. С помощью того же оператора < можно просмотреть два (и более) файла в одном потоке. Так, конструкция

$ < ~/.{zshrc,zshenv}

выведет на экран последовательно содержимое обоих основных конфигов оболочки Zsh. Кстати, шаблоны файлов в этой конструкции также не запрещены, так что можно поступить ещё проще:

$ < ~/.zsh*

Однако и это ещё не предел возможностей: если вывод нескольких файлов перенаправить в новый файл, то реализуется вековая мечта сочинителей всех времён и народов. То есть из нескольких отдельно написанных фрагментов (скажем, глав) создаётся единый текст (предположим, книги):

$ <chapter[01-10] > mybook

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

А пока заметим, что оба вида перенаправления в Zsh заменяют не только команду less (и аналогичные пейджеры), но и команду cat: для неё остаётся только использование по прямому назначению, для объединения (конкатенация) файлов.

Существуют и другие области использования расширенного и множественного перенаправления. Однако и сказанного, думаю, достаточно для осознания полезности этих механизмов. Как и командной оболочки Zsh вообще. Так что применителям дистрибутивов, отличных от Cintu, и использующим Bash можно не предаваться зависти, а перейти к Части 3.

[Общее содержание]

Добавить комментарий