Использование горячих клавиш в Bash

Использование горячих клавиш в Bash #

Командный интерфейс ориентирован на набор информации в текстовом виде. Может показаться, что разработчики данного интерфейса очень любят набирать большое количество текста. Однако это не так: зачем было бы сокращать часто используемые команды до двух-трёх символов (cp, ls, mv, rm)?

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

Документация #

Редактирование команды в командном интерфейсе #

Bash использует библиотеку Readline для реализации ввода данных от пользователя. Данная библиотека используется большинством сложных командных приложений, чтобы обеспечить комфортный ввод и редактирование сложных строк.

Мы уже видели часть возможностей данной библиотеки: можно использовать клавиши влево-вправо для перемещения внутри строки, вверх-вниз для перемещения по истории. Помимо них библиотека предоставляет большое количество возможностей, освоение которых значительно упросит использование командного интерфейса.

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

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

Перемещение курсора #

В следующем списке представлены горячие клавиши для перемещения курсора.

  • Ctrl-a — переместить курсор к началу линии.
  • Ctrl-e — переместить курсор к концу линии.
  • Ctrl-f — переместить курсор на один символ вперёд, аналогично клавише вправо.
  • Ctrl-b — переместить курсор на один символ назад, аналогично клавише назад.
  • Alt-f — переместить курсор на одно слово вперёд. Словом считается последовательность символов до пробела.
  • Alt-b — переместить курсор на одно слово назад.
  • Ctrl-l — очистить экран и переместить курсор на первую строку. Аналогично вызову команды clear.

Модифицирование текста #

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

  • Ctrl-d — удалить символ на месте курсора. Как клавиша Delete.
  • Ctrl-t — поменять местами символ под курсором с символом, который находится перед ним.
  • Alt-t — поменять местами слово под курсором со словом, которое находится перед ним.
  • Alt-l — преобразовать символы от места курсора до конца слова в нижний регистр.
  • Alt-u — преобразовать символы от места курсора до конца слова в верхний регистр.
  • Ctrl-_, C-x C-u — отменить последнюю команду редактирования. Можно отменить редактирование до самого конца.

Вырезание и вставка #

В документации библиотеки Readline используются термины killing и yanking для обозначения операций по вырезанию и вставке текста. Место для хранения данных, вырезанных из строки, называется kill-ring. В следующем списке представлены горячие клавиши по вырезанию и вставке текста.

  • Ctrl-k — вырезать, kill, текст от текущего курсора до конца сроки.
  • Ctrl-u — вырезать текст от курсора до начала сроки.
  • Alt-d — вырезать текст от курсора до конца текущего слова.
  • Alt-Backspace — вырезать текст от места курсора до начала текущего слова. Если курсор находится в начале слова, то вырезать предыдущее слово.
  • Ctrl-y — вставить, yank, текст из буфера, kill-ring, и вставить его в место текущего курсора.

Клавиша Meta #

Если Вы начнёте изучать документацию по библиотеке Readline или обратитесь к соответствующему разделу man-руководства по bash, то вы столкнётесь с термином meta key. В современных клавиатурах данная клавиша связана с символом Alt, но это было не всегда так.

Ранее, до эры PC-компьютеров, но уже при UNIX, не все могли позволить себе иметь персональный компьютер. В большинстве случаев пользователи имели доступ к терминалам. Терминал представлял собой устройство связи с большим компьютером. Терминал обычно обладал экраном и клавиатурой. Его мощности хватало для отображения текста на экране и организации взаимодействия с основным вычислителем.

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

Разработчики библиотеки не могли рассчитывать на наличие тех или иных клавиш на клавиатуре. Поэтому была изобретена клавиша meta. В современных системах это клавиша Alt. Однако можно добиться такого же эффекта, если нажать клавишу Escape, а затем нажать на вторую часть сочетания клавиш. И эта функция до сих пор поддерживается.

Завершение команд #

Другой способ, который позволяет быстро и точно набирать команды, это механизм завершения команд. Завершение случается, когда пользователь нажимает на клавишу Tab в момент набора команды. Рассмотрим пример использования.

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

/home/user/
├── Desktop/
├── Documents/
├── ls-output.txt
├── Music/
├── Pictures/
├── Public/
├── Templates/
└── Videos/

При наборе команды:

$ ls l

Нажимаем клавишу Tab:

$ ls ls-output.txt

Командный интерфейс автоматически дополнил путь, в нём точно нет проблем.

Рассмотрим другую последовательность. Пользователь набирает

$ ls D

Нажимаем клавишу Tab. В результате получим следующее:

$ ls D

Состояние вывода не изменилось. Это случилось из-за того, что D не является уникальным префиксом, по котором можно определить нужный пункт. Для работы дополнения необходимо дать больше информации. Если мы сделаем следующее:

$ ls Do

И затем нажмём на Tab, то получим:

$ ls Documents

Дополнение успешно было выполнено.

Хотя дополнение работает на формировании путей, как наиболее часто используемый случай, дополнение также работает и на переменных (словах, которые начинаются $), именах пользователей (словах, начинающихся с ~), командах (если слово стоит в начале строки), именах компьютеров (если слово начинается с @). Однако последнее дополнение будет работать только для имён служб, которые определены локально в файле /etc/hosts.

Также есть пара других горячих клавиш, которые ассоциированы с дополнением команд.

  • Alt-? — отобразить список возможных дополнений. В большинстве систем можно добиться такого же эффекта путём нажатия клавиши Tab несколько раз.
  • Alt-* — добавить все возможные варианты дополнений. Это удобно в тех случаях, когда вы хотите использовать более одного подходящего элемента.

Программное дополнение #

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

Обычно эти правила добавляются для какого-то конкретного приложения. Например возможно добавить список ключей приложения в правила автоматического дополнения. Данные правила описываются на bash и размещаются в соответствующих конфигурационных каталогах.

Некоторые библиотеки, например clickt, предоставляют разработчику возможности по формированию соответствующих скриптов.

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

Как указывалось ранее, bash сохраняет историю введённых команд. Этот список сохраняется в домашнем каталоге в файле .bash_history. Этот файл является замечательным ресурсом, который позволяет уменьшить количество вводимых данных.

Поиск в истории #

Для отображения истории команд можно воспользоваться командой history. Ввиду того, что она выводит последнюю 1000 команд, то её разумно просматривать через программу-пейджер:

$ history | less

Предположим, что мы хотим отобразить команды, в которых упоминается путь /usr/bin, для этого можно построить конвейер с приложением grep:

$ history | grep /usr/bin

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

88  ls -l /usr/bin > ls-output.txt

88 — номер линии команды в истории. Мы можем использовать его сразу же с помощью расширения строки, которое называется расширение истории. Для того, чтобы запустить нужную нам команду, можно набрать в консоли:

$ !88

bash расширит строку !88 в содержимое 88 линии в файле истории. А затем расширенная линия будет выполнена обычным образом согласно правилам обработке команд.

Интерактивный поиск #

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

Для начала инкрементального поиска необходимо нажать сочетание клавиш Ctrl-r. Затем необходимо начать вводить текст, который мы ищем. Когда необходимая команда была найдена, то можно нажать клавишу Enter, чтобы начать её выполнение.

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

Если найденная в истории команда не подошла, то можно нажать на Ctrl-r ещё раз. Тогда будет произведён поиск следующей команды в истории, которая удовлетворяет введённой последовательности символов.

Для прерывания инкрементального поиска можно нажать сочетание клавиш Ctrl-g или Ctrl+c.

Рассмотрим сценарий использования инкрементального поиска. Начальное состояние:

$

Нажимаем один раз Ctrl-r:

(reverse-i-search)`':

Приглашение изменяется, показывая, что интерпретатор работает в режиме инкрементального поиска. Поиск происходит в обратном порядке относительно порядка ввода команд, от текущего момента назад. Затем мы начинаем набирать строку, которая нас интересует. В нашем случае это /usr/bin:

(reverse-i-search)`/usr/bin': ls -l /usr/bin/ > ls-output.txt

Мы сразу находим интересующую нас команду. Мы можем её выполнить, нажав на клавишу Enter, однако мы хотим её отредактировать, поэтому нажимаем на Ctrl+j.

$ ls -l /usr/bin > ls-outuput.txt

Теперь мы вернулись в обычный режим редактирования команды. Можно редактировать команду для её выполнения.

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

  • Ctrl-p — перейти к предыдущей команде в истории команд. Такое же действие как клавиша вверх.
  • Ctrl-n — перейти к следующей команде в истории команд. Такое же действие как клавиша вниз.
  • Alt-< — перейти к началу, самому верху истории команд.
  • Alt-> — перейти к концу, к низу истории команд, т.е. к текущей команде.
  • Ctrl-r — выполнить инкрементальный поиск в истории команд. Поиск выполняется инкрементально относительно текущей линии в истории команд.
  • Alt-p — выполнить обратный неинкрементальный поиск. При использовании данного сочетания необходимо будет ввести строку, а затем нажать на клавишу ввода. Только после этого выполнится поиск.
  • Alt-n — выполнить прямой неинкрементальный поиск по истории команд.
  • Ctrl-o — выполнить текущий элемент в истории команд и передвинутся к следующему элементу. Данное сочетание полезно, если мы хотим повторить последовательность команд в истории.

Расширение истории #

Командный интерпретатор предоставляет специализированный механизм по расширению строк с использованием символа !. В рамках данного текста уже приводился пример по запуску команды по номеру в истории команд. Рассмотрим другие варианты использования данного расширения.

  • !! — повторить последнюю команду. Однако перейти к предыдущей команде и выполнить её запуск скорее проще.
  • !number — повторить выполнение команды по номеру в истории команд.
  • !string — повторить выполнение команды, которая начинается на указанную строку.
  • !?string — повторить выполнение команды, которая включает в себя указанную строку.

Стоит отметить, что не стоит злоупотреблять формами ?string и !?string, так как сложно быть уверенным в той команде, которая будет выполнена после выполнения расширения.

Задачи #

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

При решении задач рекомендуется использовать эмуляторы терминала, которые не перехватывают сочетания горячих клавиш. Примером такого эмулятора может служить kitty.

Базовое передвижение в строке #

Откройте справочную страницу по интерпретатору bash. Перейдите в раздел READLINE и секцию Commands for Moving. Используйте это руководство для решения следующих задач.

  1. Введите в командном интерфейсе строку С чердака достали рамы: протирает стёкла мама. Мы ей будем помогать окна на зиму вставлять. Курсор после ввода должен остаться в конце строки.
  2. С помощью сочетания клавиш переместитесь к началу строки.
  3. С помощью действия движения на один символ переместитесь к двоеточию.
  4. С помощью сочетания клавиш переместитесь к концу строки.
  5. С помощью действия движения на один символ назад переместитесь к слову мама.
  6. С помощью действия движения на одно слово вперёд переместитесь к концу слова зиму.
  7. С помощью действия движения на одно слово назад переместитесь к началу слова стёкла.

Изменение текста #

Откройте справочную страницу по интерпретатору bash. Перейдите в раздел READLINE и секцию Commands for Changing Text. Используйте это руководство для решения следующих задач.

  1. Введите в командном интерфейсе строку Много листьев мы набрали, на них нитки нанизали и повесили гирляндой на крыльцо и на веранду..
  2. С помощью сочетания клавиш переместитесь к началу слова гирляндой.
  3. С помощью сочетания клавиш удалите данное слово.
  4. С помощью сочетания клавиш переместитесь к предлогу на.
  5. С помощью сочетания клавиш поменяйте местами буквы н и а.
  6. С помощью сочетания клавиш переместитесь к слову гирляндой.
  7. С помощью сочетания клавиш переместите данное слово в конец предложения.
  8. С помощью сочетания клавиш переместитесь в начало строки.
  9. С помощью сочетания клавиш приведите слово Много к верхнему регистру.

Вырезание и вставка #

Откройте справочную страницу по интерпретатору bash. Перейдите в раздел READLINE и секцию Killing and Yanking. Используйте это руководство для решения следующих задач.

  1. Введите в командном интерфейсе строку чтобы рамы не сырели, чтобы стёкла не потели. Это вата. Здесь песок. Между стёкол уголёк,
  2. С помощью сочетания клавиш переместитесь к началу слова Это.
  3. С помощью действия вырезания поместите в буфер окончание строки.
  4. С помощью сочетания клавиш вернитесь в начало строки.
  5. С помощью действия вставки вставьте содержимое буфера в начало строки.
  6. С помощью сочетания клавиш перейдите к последней запятой в приложении.
  7. С помощью действия вырезания поместите в буфер начало строки.
  8. С помощью сочетания клавиш перейдите к концу строки.
  9. С помощью действия вставки вставьте содержимое буфера в конец строки.
  10. С помощью сочетания клавиш и действий вырезания слова поменяйте местами слова вата и песок.
  11. С помощью сочетания клавиш и действий вырезания предыдущего слова поменяйте местами слова стёкла и потели.

История команд #

Откройте справочную страницу по интерпретатору bash. Перейдите в раздел READLINE и секцию Commands for Manipulating the History. Используйте это руководство для решения следующих задач.

Выполните следующие команды:

  1. Создайте следующее дерево каталогов в домашнем каталоге:
    test/
    ├── small/
    │   ├── big/
    │   ├── making/
    │   └── progress/
    └── things/
        ├── big/
        ├── making/
        └── progress/
  2. В каждом каталоге поместите по пустому файлу. Названия файлов должны отличаться.
  3. Отобразите историю запуска команд.
  4. Найдите команду по созданию пустого файла в каталоге test/small/progress. Выясните её порядковый номер.
  5. Повторите данную команду с использованием команды расширения по номеру.
  6. Перейдите в каталог /tmp.
  7. С помощью рекурсивного поиска найдите команду по созданию каталога test/things/big.
  8. Отредактируйте данную команду, чтобы в каталоге /tmp появились подкаталоги test/linux/big.
  9. Создайте в домашнем каталоге каталог repeat и перейдите в него.
  10. С помощью рекурсивного поиска найдите команды по созданию изначального дерева каталогов.
  11. Повторите все команды по созданию каталогов и пустых файлов с помощью сочетания горячих клавиш. Удалось ли создать полную копию данных каталогов?

© A. M. Васильев, 2022, CC BY-SA 4.0, andrey@crafted.su