Linux Mint и его Cinnamon. Очерки применителя - Алексей Федорчук
Шрифт:
Интервал:
Закладка:
Значение управляющих последовательностей не ограничивается командной строкой — большинство популярных в POSIX-мире текстовых редакторов, от простых Nano или joe до грандиозного vim и монструозного emacs. построены по тому же принципу. Так что навыки, полученные при работе с keybindings, например, в Bash, весьма поспособствуют виртуозному освоению любого из этих инструментов.
И второе — действие ключевых последовательностей, как правило. не зависит не только от типа терминала и физического устройства клавиатуры, но и от ее раскладки — при переключении на кириллицу они будут работать столь же справно, как и в латинице.
История команд
Возможности навигации и редактирования строки особенно ярко проявляются в сочетании с другой замечательной особенностью, предоставляемой командными оболочками — доступом к истории команд. То есть: раз введенная в строке команда не уходит в небытие после исполнения, а помещается в специальный буфер памяти. Который, как и все в Unix'ах, именуется весьма незатейливо — буфер истории команд. Откуда команда (со всеми её опциями и аргументами) может быть извлечена для повторного использования. Или — для редактирования и исполнения в новой реинкарнации.
Буфер истории команд сохраняется в течении всего сеанса работы. Однако в большинстве случаев командные оболочки настраиваются так, что по выходе из сеанса буфер истории сохраняется в специальном файле в домашнем каталоге пользователя, и таким образом его содержимое оказывается доступным при следующем запуске шелла. Имя этого файла может быть различным в разных оболочках, но обычно включает компонент history (в Bash — ~/.bash_history).Так что, можно сказать, что введенным нами командам суждена вечная жизнь.
Конечно, не совсем вечная. И размер буфера истории команд, и количество строк в файле истории — величины конечные. Так что, если установленный предел превышен, то старые команды вытесняются более новыми. Однако и величину буфера, и количество строк в файле истории можно установить любыми. Разумеется, в разумных пределах — не знаю, существует ли принципиальное ограничение на их размер, за исключением объёма памяти и дискового пространства. А если учесть, что и из буфера, и из памяти с помощью соответствующих настроек (со временем я расскажу, каких) можно исключить дубликаты и ещё кое-какой мусор — то мое заявление о вечной жизни команд не выглядит столь уж преувеличенным.
Универсальное средство доступа к буферу истории команд — специальная команда, встроенная во все шеллы, таковой поддерживающие — history (в большинстве дистрибутивов Linux она по умолчанию имеет псевдоним — h). Данная без опций, эта команда выводит полный список команд в их исторической (издревле к современности) последовательности, или некоторое количество команд, определенных соответствующими настройками (о которых будет говориться позднее).
В качестве опции можно указать желаемое количество одновременно выведенных команд. Например, директива
$ history -2
выведет две последние команды из буфера истории вместе с их номерами:
1023 joe shell.html
1024 less ~/.zshrc
Любая из команд в буфере истории может быть повторно запущена на исполнение. Для этого достаточно набрать в командной строке символ ! (восклицательный знак) и затем, без пробела — номер команды в списке буфера. Например,
$ !1023
для приведенного выше примера повторно откроет файл shell.html в текстовом редакторе joe.
Другой способ доступа к командам из буфера истории — комбинации клавиш Control+P и Control+N, служащие для последовательного его просмотра (как бы «пролистывания») назад и, соответственно, вперед (разумеется, если есть куда). Они дублируются клавишами управления курсором Up и Down (назад и вперед, соответственно). Кроме того, последовательности Meta+< и Meta+&rt; обеспечивают переход к первой и последней команде в буфере истории.
Любая извлеченная (с помощью стрелок или управляющими последовательностями) из буфера истории в текущую строку команда может быть повторно запущена на исполнение — нажатием клавиши Enter или дублирующей ее комбинацией Control+M. причём предварительно ее можно отредактировать — изменить опции, или аргументы, — точно так же, как и только что введенную.
Поиск в истории
Во всех современных «развитых» шеллах предусмотрены средства поиска команды в буфере истории — простым перебором (обычно Meta+P — назад и Meta+N — вперед).
Впрочем, не смотря на громкое название, обычный поиск ничем практически не отличается от пролистывания исторического списка курсорными стрелками. Что при обширной истории команд может быть весьма утомительным. И потому для ее облегчения предусмотрена такая интересная возможность, как наращиваемый поиск (incremental search) нужной команды в буфере истории по одному (или нескольким) из составляющих ее символов.
Выполняется инкрементный поиск так: после нажатия (при пустой командной строке) клавишной комбинации Control+R появляется предложение ввести алфавитный символ (или — последовательность символов произвольной длины), заведомо входящий в состав требуемой команды:
$ bck-i-search: _
Ввод такого символа выведет последнюю из команд, его содержащих. При этом введенный символ будет отмечен знаком курсора. Он не обязан входить в имя команды, но может быть составляющим ее опций или аргументов (имени файла или пути к нему, например). Следующее нажатие Control+R зафиксирует курсор на предыдущем символе, в пределах этой же или более ранней по списку команды, и т.д. Однако вместо этого в строке поиска можно вводить дополнительные символы, детализирующие условия поиска команды (или — ее опций и аргументов).
Процедуру поиска можно продолжать вплоть до достижения требуемого результата — то есть нахождения той команды, которая нужна именно сейчас. Нажатие клавиши Enter в любой из этих моментов запускает найденную (то есть помещённую в командную строку) команду на исполнение, с завершением поиска. Поиск обрывается также и нажатием комбинации Control+C. Перед запуском найденная команда может быть отредактирована стандартными средствами — с использованием управляющих последовательностей.
Регулярные выражения
Как известно, все пользователи-POSIX'ивисты должны быть в обязательном порядке привержены одному из семи смертных грехов. И грех этот — леность, можно сказать, показатель профессиональной пригодности линуксоида. В соответствие со своей леностью разработчики POSIX-систем придумывают способы, как бы им минимизировать свои усилия. А применители из лени изощряются в использовании этих приемов на практике. В частности — в том, как свести к минимуму набор в командной строке.
Собственно говоря, этой цели служили почти все приемы, описанные выше. Осталось осветить немногое. А именно — регулярные выражения, реализуемые с помощью т.н. специальных символов (или метасимволов).
Элементарная, и весьма частая, в духе школьных, задача: из каталога dir1 требуется скопировать все файлы в каталог dir2. Так неужели все они должны быть перечислены в качестве аргументов команды cp? Нет, нет, и ещё раз нет. Ибо для этой цели придуманы шаблоны имен файлов. Самый часто используемый из них — специальный символ * (вроде бы я о нем уже говорил?). Он подменяет собой любое количество любых символов (в том числе — и нулевое, то есть отсутствие символов вообще). То есть для решения предложенной задачи нам достаточно дать команду:
$ cp dir1/* dir2
Чуть усложним условия: к копированию из dir1 предназначены не все файлы, а только html-документы, традиционно имеющие суффикс html. Решение от этого не становится сложнее:
$ cp dir1/*html dir2
Однако тут можно вспомнить, что html-документы могут иметь и расширение htm. Не пропустим ли мы их таким образом при копировании? Таким — безусловно, пропустим. Однако нам на помощь придет другой шаблон — символ ?. А соответствует он любому единичному символу (или — его отсутствию, т.е. символу null). И значит, если команда из примера будет модифицирована таким образом:
$ cp dir1/*htm? dir2
то она гарантированно охватит все возможные маски html-документов.
Вроде все хорошо. Однако нет: из каталога dir1 нам нужно скопировать только три определенных файла — file1, file2, file3. Не придется ли каждый из них указывать в командной строке с полным путем (а ведь они могут быть и в глубоко вложенном подкаталоге типа dir1/dir11/dir111)? Все равно не придется, на столь хитрую... постановку задачи у нас есть прием с левой резьбой — символы группировки аргументов, обозначаемые фигурными скобками. Что на практике выглядит так:
$ cp path/{file1,file2,file3} dir2
И приведет к единоразовому копированию всех трех файлов в каталог dir2. Заметим, что сгруппированные аргументы разделяются запятыми без пробелов. И ещё: в оболочке Bash группируемые аргументы придется полностью вводить руками. Но вот в Zsh на них распространяется возможность автодополнения, да и запятая после каждого имени появляется автоматически (и столь же автоматически исчезает при закрытии фигурной скобки).