UnixMountainSkiFun

Unix Горы Лыжи

16-06-2008 15:29

Bash. Режим редактирования командной строки в стиле VI


Автор:
Исходный текст:
Peteris Krumins
http://www.catonmat.net/blog/bash-vi-editing-mode-cheat-sheet/

Bash обеспечивает два режима редактирования командной строки -- emacs и vi. Режим emacs установлен по-умолчанию, и описан мной в статье. Кроме этого я создал шпаргалку по этому режиму.

Теперь же я хочу познакомить вас с режимом редактирования bash в стиле vi (vi editing mode), и предоставить детальную шпаргалку с клавиатурными сокращениями этого режима, установленными по-умолчанию (default keyboard mappings).

Разница между этими двумя режимами состоит назначенных клавиатурных комбинациях (или клавишах). Увидеть текущие назначенные клавиатурные комбинации можно с помощью встроенной в bash-команды bind:

 $ bind -P

 abort can be found on "\C-g", "\C-x\C-g", "\M-\C-g".
 accept-line can be found on "\C-j", "\C-m".
 alias-expand-line is not bound to any keys
 ...

Чтобы перейти в режим редактирования в стиле vi наберите в своем bash shell (чтобы вернуться к режиму emacs, наберите set -o emacs)

 $ set -o vi

Если вы используете редактор vi, то почувствуете себя как дома.

Редактирование возможно в двух режимах -- командный режим (command mode) и режим добавления (insert mode). Все, что вы набираете в режиме добавления тут же появляется на терминале, а в командном режиме клавиши используются для исполнения различных команд.

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

Обозначим положение курсора, в режиме добавления, символами '[i]', а символами '[c]' -- в командном режиме.

Примеры:

Когда вы измените режим редактирования на vi (набором set -o vi), то попадаете в режиме добавления.

Вот что должно получиться:

 $ echo arg1 arg2 arg3 arg4[i]

Пример 1:

Предположим, что вы набрали команду с несколькими аргументами и желаете добавить еще один аргумент перед arg2 (т.е. надо вернуться на три слова назад).

 $ echo arg1 (здесь надо дописать arg5) arg2 arg3 arg4[i]

Нажмите 'ESC', чтобы перейти в командный режим, а затем нажмите '3' и 'B':

 $ echo arg1 [c]arg2 arg3 arg4

Можно, конечно, нажать 'B' три раза, -- 'BBB'.

Теперь, с помощью нажатия 'i' вернемся в режим добавления, и наберем 'arg5 '.

 $ echo arg1 arg5 [i]arg2 arg3 arg4

Пример 2:

Допустим, что теперь вам требуется изменить arg2 на arg5:

 $ echo arg1 [c]arg2 arg3 arg4

Для этого наберите на клавиатуре 'cw' (это означает изменить слово (change word)), а потом 'arg5':

 $ echo arg1 arg5[c] arg3 arg4

Или, более кратко, можете набрать 'f2r5', -- здесь 'f2' перемещает курсор вправо, до первого появления символа '2', а 'r5' заменяет символ под курсором на '5'.

Пример 3:

Предположим, вы набрали длинную команду и обнаружили, что сделали несколько ошибок, а теперь желаете их исправить непосредственно в редакторе vi. Для этого можно нажать клавишу 'v', и отредактировать команду в редакторе, а не в командной строке!

Пример 4:

Допустим, вы набираете длинную команду и вдруг вспоминаете, что перед ней нужно выполнить другую. Нет нужды стирать только что набранную команду! Можно переключиться в командный режим, нажатием ESC, а затем использовать '#', -- это закомментирует текущую команду в истории команд (command history). После того как наберете забытую вами команду, можено вернуться по истории на две команды назад, нажатием 'kk' (или '2k'), стереть символ '#', который был добавлен в качестве комментария, и выполнить команду, -- в результате вся команда будет выглядеть, например, так 'ESC 2k0x ENTER'.

Это очень простые примеры, но здесь и не предполагалось излагать ничего сложного. Просмотрите мою шпаргалку, и найдете там другие подсказки и примеры, -- попробуйте их!

Чтобы создать эту шпаргалку, я загрузил исходный код bash-2.05b, просканировал файлы lib/readline/vi_keymap.c и lib/readline/vi_mode.c на предмет клавиатурных сокращений по-умолчанию.

В результате выяснилось, что все команды, полученные из vi_keymap.c документированы в man 3 readline, и ничего нового обнаружить не удалось.

Далее, чтобы выявить как изменились клавиатурные сочетания по-умолчанию, я проверил функцию initialize_readline, исходного файла bashline.c. Я обнаружил, что 'CTRL-e', который переключает из режима vi в режим emacs, стал неопределенным; 'v' -- определен, и открывает текущую строку в редакторе; а '@' -- заменяет клавишу макро (символ) текущей строкой.

Ниже следует шпаргалка, которая включает в себя:

  • Команды перехода в режим ввода,
  • Основные команды перемещения,
  • Команды поиска символа,
  • Команды удалений,
  • Команды undo, redo и copy/paste,
  • Команды манипуляции с историей,
  • Команды автозавершения,
  • Прочие команды, а также
  • Подсказки и примеры.

Шпаргалка в других форматах (pdf и tex), в английском варианте, доступны на сайте автора.

 .---------------------------------------------------------------------------.
 |                                                                           |
 |                          Readline VI Editing Mode                         |
 |                     Default Keyboard Shortcuts for Bash                   |
 |                               Cheat Sheet                                 |
 |                                                                           |
 '---------------------------------------------------------------------------'
 | Peteris Krumins (peter@catonmat.net), 2008.01.08                          |
 | http://www.catonmat.net  -  good coders code, great reuse                 |
 |                                                                           |
 | Released under the GNU Free Document License                              |
 '---------------------------------------------------------------------------'

  ======================== Keyboard Shortcut Summary ========================

 .---------------------------------------------------------------------------.
 |              |                                                            |
 | Клавиатурная | Описание                                                   |
 |  комбинация  |                                                            |
 |              |                                                            |
 '---------------------------------------------------------------------------'
 | Переключение в КОМАНДНЫЙ режим:                                           |
 '---------------------------------------------------------------------------'
 | ESC          | Переключение в командный режим.                            |
 '---------------------------------------------------------------------------'
 | Команды для перехода в режим ВВОДА:                                       |
 '---------------------------------------------------------------------------'
 | i            | Добавление текста перед курсором.                          |
 '--------------+------------------------------------------------------------'
 | a            | Добавление текста после курсора.                           |
 '--------------+------------------------------------------------------------'
 | I            | Добавить текст в начале строки.                            |
 '--------------+------------------------------------------------------------'
 | A            | Добавить текст в конце строки.                             |
 '--------------+------------------------------------------------------------'
 | c<mov. comm> | Изменить текст в направлении <mov. comm> (смотри ниже).    |
 '--------------+------------------------------------------------------------'
 | C            | Изменить текст в конце строки (эквивалент c$).             |
 '--------------+------------------------------------------------------------'
 | cc или S     | Тзменить текущую строку (эквивалент 0c$).                  |
 '--------------+------------------------------------------------------------'
 | s            | Удалить один символ под курсором и войти в режим           |
 |              | добавления (эквивалент c[SPACE]).                          |
 '--------------+------------------------------------------------------------'
 | r            | Заменяет один символ под курсором                          |
 |              | (не выходя из командного режима).                          |
 '--------------+------------------------------------------------------------'
 | R            | Заменяет символы под курсором.                             |
 '--------------+------------------------------------------------------------'
 | v            | Редактирует (и исполняет) текущую команду в текстовом      |
 |              | редакторе (редактор определяется в переменных $VISUAL или  |
 |              | $EDITOR, либо vi).                                         |
 '--------------'------------------------------------------------------------'
 | Основные команды перемещения (в командном режиме):                        |
 '--------------.------------------------------------------------------------'
 | h            | Переместиться на один символ вправо.                       |
 '--------------+------------------------------------------------------------'
 | l            | Переместиться на один символ влево.                        |
 '--------------+------------------------------------------------------------'
 | w            | Переместиться на одно слово (или токен) вправо.            |
 '--------------+------------------------------------------------------------'
 | b            | Переместиться на одно слово (или токен) влево.             |
 '--------------+------------------------------------------------------------'
 | W            | Переместиться на одно непустое слово вправо.               |
 '--------------+------------------------------------------------------------'
 | B            | Переместиться на одно непустое слово влево.                |
 '--------------+------------------------------------------------------------'
 | e            | Переместиться на конец текущего слова.                     |
 '--------------+------------------------------------------------------------'
 | E            | Переместиться на конец текущего непустого слова.           |
 '--------------+------------------------------------------------------------'
 | 0            | Перейти в начало строки.                                   |
 '--------------+------------------------------------------------------------'
 | ^            | Перейти на первый непустой символ строки.                  |
 '--------------+------------------------------------------------------------'
 | $            | Перейти в конец строки.                                    |
 '--------------+------------------------------------------------------------'
 | %            | Перейти к соответствующей открывающей/закрывающей скобке.  |
 '--------------'------------------------------------------------------------'
 | Команды поиска символа (это тоже команды перемещения):                    |
 '--------------.------------------------------------------------------------'
 | fc           | Перейти к следующему появлению символа c.                  |
 '--------------+------------------------------------------------------------'
 | Fc           | Перейти влево, к предыдущему появлению символа c.          |
 '--------------+------------------------------------------------------------'
 | tc           | Перейти вправо, к следующему появлению символа c, а потом  |
 |              | на один символ назад.                                      |
 '--------------+------------------------------------------------------------'
 | Tc           | Перейти влево, к предыдущему появлению символа c, а потом  |
 |              | на символ вперед.                                          |
 '--------------+------------------------------------------------------------'
 | ;            | Повторить последнюю команду поиска.                        |
 '--------------+------------------------------------------------------------'
 | ,            | Отменить последнюю команду поиска в противоположном        |
 |              | направлении.                                               |
 '--------------+------------------------------------------------------------'
 | |            | Перейти к n-ому столбцу (можно указать аргумент n, набирая |
 |              | его на цифровой клавиатуре, например, 20|)                 |
 '--------------'------------------------------------------------------------'
 | Команды удалений:                                                         |
 '--------------.------------------------------------------------------------'
 | x            | Удаляет один символ под курсором.                          |
 '--------------+------------------------------------------------------------'
 | X            | Удаляет один символ перед курсором.                        |
 '--------------+------------------------------------------------------------'
 | d<mov. comm> | Удаляет текст в направлении движания (смотри выше).        |
 '--------------+------------------------------------------------------------'
 | D            | Удалить до конца строки (эквивалент d$).                   |
 '--------------+------------------------------------------------------------'
 | dd           | Удалить текущую строку (эквивалент 0d$).                   |
 '--------------+------------------------------------------------------------'
 | CTRL-w       | Удалить предыдущее слово.                                  |
 '--------------+------------------------------------------------------------'
 | CTRL-u       | Удалить от курсора и до начала строки.                     |
 '--------------'------------------------------------------------------------'
 | Команды Undo, Redo и Copy/Paste:                                          |
 '--------------.------------------------------------------------------------'
 | u            | Выполнить Undo предыдущей модификации текста.              |
 '--------------+------------------------------------------------------------'
 | U            | Undo всех предыдущих модификаций текста.                   |
 '--------------+------------------------------------------------------------'
 | .            | Redo последней модификации текста.                         |
 '--------------+------------------------------------------------------------'
 | y<mov. comm> | Скопировать в буфер (Yank) в направлении.                  |
 '--------------+------------------------------------------------------------'
 | yy           | Скопировать в буфер всю строку.                            |
 '--------------+------------------------------------------------------------'
 | p            | Вставить скопированный текст под курсором.                 |
 '--------------+------------------------------------------------------------'
 | P            | Вставить скопированные текст перед курсором.               |
 '--------------'------------------------------------------------------------'
 | Команды работающие с историей команд:                                     |
 '--------------.------------------------------------------------------------'
 | k            | Переместиться назад на одну команду в истории.             |
 '--------------+------------------------------------------------------------'
 | j            | Переместиться вперед на одну команду в истории.            |
 '--------------+------------------------------------------------------------'
 | G            | Переместиться на строку истории n (n можно указать         |
 |              | с использованием цифровой клавиатуры, например 15G).       |
 '--------------+------------------------------------------------------------'
 | /string или  | Поиск назад в истории команды, совпадающей с string.       |
 | CTRL-r       |                                                            |
 '--------------+------------------------------------------------------------'
 | ?string or   | Поиск вперед в истории команды, совпадающей с string.      |
 | CTRL-s       | (Заметим, что на большинстве компьютеров Ctrl-s прекратит  |
 |              | терминальный вывод, изменить можно с помощью `stty'        |
 |              | (Ctrl-q продолжит терминальный вывод)).                    |
 '--------------+------------------------------------------------------------'
 | n            | Повторить поиск в том же направлении, что и ранее.         |
 '--------------+------------------------------------------------------------'
 | N            | Повторить поиск в противоположном предыдущему направлению. |
 '--------------'------------------------------------------------------------'
 | Команды автозавершения:                                                      |
 '--------------.------------------------------------------------------------'
 | TAB или =    | Список всех возможных автозавершений.                      |
 | или CTRL-i   |                                                            |
 '--------------+------------------------------------------------------------'
 | *            | Вставить все возможные автозавершения.                     |
 '--------------'------------------------------------------------------------'
 | Прочие команды:                                                           |
 '--------------.------------------------------------------------------------'
 | ~            | Инвертировать регистр символа под курсором и переместиться |
 |              | на символ вправо.                                          |
 '--------------+------------------------------------------------------------'
 | #            | Предварить строку символом '#' (символ комментария)        |
 |              | и отправить ее в историю.                                  |
 '--------------+------------------------------------------------------------'
 | _            | Вставить n-ое слово предыдущей команды в текущую строку.   |
 '--------------+------------------------------------------------------------'
 | 0, 1, 2, ... | Устанавливает числовой аргумент.                           |
 '--------------+------------------------------------------------------------'
 | CTRL-v       | Литеральная вставка символа (экранированный ввод).         |
 '--------------+------------------------------------------------------------'
 | CTRL-r       | Транспозиция (обмен) двух символов.                        |
 '--------------'------------------------------------------------------------'


  ===========================================================================

 .---------------------------------------------------------------------------.
 | Peteris Krumins (peter@catonmat.net), 2008.01.08.                         |
 | http://www.catonmat.net  -  good coders code, great reuse                 | 
 |                                                                           |
 | Released under the GNU Free Document License                              |
 '---------------------------------------------------------------------------'

Примеры и подсказки

  • Некоторые команды используют <команду перемещения> (<movement command>). Такие команды применяют над собой передвижение. Например, d$ использует $ в качестве перемещения, которое перемещает курсор в конец строки, таким образом, будет удален весь текст, от текущего положения курсора и до конца строки. Другим примером является команда cfA, которая использует fA в качестве перемещения, которое находит следующее появление символа A, а значит, вся команда целиком будет изменять в строке все символы A.
  • Используйте CTRL-v чтобы выполнить литеральную вставку символа, например, CTRL-v CTRL-r вставит CTRL-r в командную строку.
  • Смотрите man bash и man readline, используйте встроенную команду bind для изменения поведения по-умолчанию.

<< VI. Курс молодого бойца | UNIX | Data Munging with Perl >>


edit RightSideBar