Использование быстрых клавиш в командной строке Linux (BASH)

    Эта статья посвящена наиболее часто используемым комбинациям клавиш при работе в командной строке Linux (в основном в командном интерпретаторе bash).

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

    Никогда не развивал навыка быстрой печати, но знание не одного десятка hotkey'ев, перечисленных в этом материале, позволяет набирать команды со скоростью мысли.

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


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

    Общие слова и замечания

    Большинство продемонстрированных клавиш стандартны для «командной строки Linux», но часть из этих комбинаций специфичны для bash (поэтому и пометил это в заголовке). На текущий момент BASH – наиболее распространенный командный интерпретатор, используемый по умолчанию в большинстве Linux-дистрибутивов. В других командных интерпретаторах или, проще говоря, shell'ах (рекомендую попробовать zsh и fish) могут быть небольшие отличия в работе. Также часть комбинаций прописана в «настройках по умолчанию» (например, в файле /etc/inputrc или в /etc/bashrc), которые тоже могут различаться в разных дистрибутивах. И бывает, что некоторые клавиши могут быть настроены и перехватываться графической оболочкой, в которой запущен командный интерпретатор.

    Если вдруг что-то из указанного мной в этой статье у вас не сработало, пишите в комментариях «название - версию shell и название - версию дистрибутива».

    Часть демонстрируемых клавиш относятся к «настройкам терминала». А часть – клавиши из командного интерпретатора BASH, и их можно посмотреть, почитав мануал по bash'у (огромный текст – пользуйтесь поиском):

    man bash

    [00:10:40]
    [00:10:40]

    ^^^ На приведенном фрагменте из мануала: Запись «(C-r)» означает Ctrl-r, а «M->» означает Alt->.

    «M» - это «Meta-клавиша»

    Из истории: «М» - это «Metа-клавиша», сейчас вместо неё используется клавиша Alt, либо клавишаEsc. Я чаще в её качестве буду использовать клавишу Alt.

    Замечание: Если у кого-то настроено переключение раскладки по комбинации Alt-Shift, то учитывайте, что в комбинациях, перечисленных далее и содержащих Alt-Shift, вам надо будет использовать скорее клавишу Esc-Shift (или поменять комбинацию для переключения раскладки клавиатуры, у меня, например, раскладка переключается по CapsLock).

    [00:11:18]
    [00:11:18]

    ^^^ Здесь показано на примере использования комбинаций для перемещения по «словам» командной строки: Alt-b(или, что то же самое, Esc-b) и Alt-f(или, что то же самое, Esc-f)

    Для демонстраций нажатых клавиш использую утилиту «screenkey».

    Upd: При этом стоит упомянуть, что по умолчанию bash использует emacs-режим редактирования командной строки и поэтому многие комбинации клавиш пришли из редактора emacs. Для знающих редактор vi, могу порекомендовать переключить (добавив "set -o vi" в ~/.bashrc) bash в vi-режим редактирования и пользоваться привычными комбинациями из vi.

    Терминал

    Итак, начнем с клавиш из настроек терминала. Их можно посмотреть, выполнив команду:
    stty -a

    А перенастроить, например, так:
    stty intr НоваяКлавиша

    Ctrl-c – сигнал SIGINT

    Первые две комбинации клавиш достаточно важные, и часто «недавно перешедшие с Windows на Linux» НЕправильно их используют: продолжая, как в DOS, для завершения команд использовать комбинацию «Ctrl-z», что неверно. В Linux же для того, чтобы попросить (команде посылается сигнал SIGINT) приложение прервать свою работу, используется Ctrl-c.

    [00:14:24]
    [00:14:24]

    Ctrl-z – сигнал SIGTSTP

    А комбинация Ctrl-z используется, чтобы попросить (команде посылается сигнал SIGTSTP) приложение остановить свою работу (не завершая) – «поставить на паузу». Ну, а «разбудить» его можно командой «fg» (или «bg»).

    [00:14:36]
    [00:14:36]

    Ctrl-d – EOF(окончание ввода данных)

    Далее разберем комбинацию Ctrl-d. В выводе «stty -a» эта комбинация значится как «EOF», что означает «окончание ввода данных». Для примера покажу, как можно создать текстовый файл с определенным текстом без использования текстового редактора:

    [00:15:51]
    [00:15:51]

    ^^^ Здесь видно, что любой набираемый текст перенаправляется в файл /tmp/File.txt, и нет никакой фразы (типа «Горшочек, не вари»), которую бы команда cat восприняла как «окончание ввода» – точнее, для этого как раз и надо нажать Ctrl-d.

    Также пользуюсь комбинаций Ctrl-d для того, чтобы выйти из консоли (например, после того как переключился командой su под другого пользователя или зайдя по ssh на другую машину) – вместо набора команды «exit» или «logout»:

    [00:17:44]
    [00:17:44]

    ^^^ В правом терминале отображаю историю команд.

    ...(а внимательный зритель догадается, какой «супер-секретный» пароль у root'а на стенде)

    Ctrl-v – ввод следующего символа

    Комбинация Ctrl-v позволяет вставить в командную строку следующий за ней символ, не воспринимая его как спецсимвол. (Параметр lnext в выводе «stty -a»)

    [00:19:19]
    [00:19:19]

    ^^^ Здесь для примера показываю, как в скрипте выводить строку текста с использованием табуляции (знаю, что можно использовать \t в команде echo: echo -e "\tTEXT", но не у всех утилит есть такая возможность, а подобная необходимость вставить «спецсимвол» случается).

    [00:20:38]
    [00:20:38]

    ^^^ А в этом примере у меня есть файл «New Text Document.txt», созданный в ОС Windows при помощи программы Notepad в директории, которую я затем открыл на доступ по сети и примонтировал в Linux в директорию /mnt. Программа Notepad (в отличии от Notepad++) создает файл в DOS-формате – в конце каждой строки использует дополнительный символ «Возврат каретки». Терминалы часто по умолчанию этот символ не отображают, но он есть, и поэтому, например, команда 'grep "m$" /mnt/New\ Text\ Document.txt' не выведет строку, заканчивающуюся на букву «m». Команда cat с опцией «-v» отображает этот символ. А для того, чтобы при выводе заменить или удалить это символ, воспользовался командой tr (хотя можно было бы использовать специальную для этого утилиту unix2dos).

    Ctrl-l – очищает экран

    Комбинация Ctrl-l – «очищает» экран.

    [00:10:51]
    [00:10:51]

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

    «Работа с историей команд» – классическая тема обычно из любого начального курса по Linux (по крайней мере, среди тех курсов, которые читаются у нас в «Сетевой Академии ЛАНИТ»). И многие, кто имеет хотя бы небольшой опыт работы с командной строкой, историей команд пользуются – как минимум знают, что она есть, и используют стрелки «вверх» (отобразить предыдущую команду) и «вниз» (отобразить следующую после отображаемой команду в истории команд), чтобы выбрать, какую из ранее введенных команд либо снова выполнить, либо подредактировать и запустить отредактированную. Но помимо стрелок еще есть ряд полезных комбинаций клавиш, которые позволяют работать с историей команд, – быстрее находить нужные команды.

    Ctrl-r – Поиск по истории

    Комбинация Ctrl-r позволяет искать в истории команд команды, содержащие указанный далее текст.

    [00:25:21]
    [00:25:21]

    ^^^ В этом примере мне понадобилось из истории вытащить команду, содержащую текст «su»: нажав Ctrl-r и набрав искомый текст «su», я увидел самую недавнюю команду, содержащую «su»; при повторном нажатии Ctrl-r отображается предыдущая команда, содержащая «su» и т.д. При необходимости изменить команду жму стрелку «вправо» и правлю текст, а чтобы запустить команду - нажимаю Enter.

    PgUp/PgDown – Поиск по истории

    PgUp – отображает предыдущую команду начинающуюся с уже введенного текста, PgDown – следующую.

    [00:27:35]
    [00:27:35]

    ^^^ В этом примере перемещаюсь между командами, начинающимися с «cat». (Часто также ищу команды, начинающиеся с «sudo». Или если мне нужно снова отредактировать какой-то файл, который недавно редактировал: набираю «vi», жму несколько раз PgUp, а затем Enter.)

    В дистрибутивах где это настроено - в /etc/inputrc есть строки:
    "\e[5~":	history-search-backward
    "\e[6~":	history-search-forward

    Alt-_/Alt-./Alt-- – вставка аргументов

    Комбинация Alt-_ (выполняется нажатием Alt, Shift, -) – вставляет последний аргумент из предыдущих команд. (Аналогично работает комбинация Esc-. или, что то же самое, Alt-.)

    [00:28:32]
    [00:28:32]

    ^^^ В данном примере видно, как повторные нажатия Alt-_ вставляют аргументы от пред-пред-…-идущих команд.

    Комбинация Alt - – позволяет указать (порядковый номер с конца), какой аргумент вставить клавишей Alt-_ из предыдущей команды.

    [00:30:13]
    [00:30:13]

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

    Alt-# – текущую команду преобразовать в комментарий

    Бывает, во время набора очень длинной команды понимаю, что мне нужно что-нибудь посмотреть или дополнительно сделать (например, глянуть, какие файлы есть в определенной директории, прочитать мануал по команде, установить нужный пакет…). Что делать с уже набранным текстом? Хотелось бы посмотреть нужную информацию и продолжить набирать команду, а не начинать печатать её сначала. Alt-# (выполняется нажатием Alt, Shift, 3. Также можно использовать Esc-#) – преобразует текущую набранную команду в комментарий в истории – добавляет символ «#» в начало строки и добавляет полученную строку в историю команд.

    [00:32:03]
    [00:32:03]

    Ctrl-o – повтор команд из истории

    Комбинация Ctrl-o позволяет повторять серию команд из истории. То есть нужно из истории команд стрелками выбрать первую команду из серии и нажать Ctrl-o – это выполнит текущую команду и выведет из истории следующую. Дальше можно продолжать нажимать Ctrl-o с тем же эффектом.

    [00:33:58]
    [00:33:58]

    ^^^ В примере я написал три команды: одна увеличивает на 1 переменную, которой соответствует год; вторая выводит переменную-год; третья показывает, сколько дней в феврале в указанном году. Дальше, нажимая Ctrl-o, повторяю эту серию из трех команд много раз (один кадр соответствует трем нажатиям).

    Автодополнение

    Tab – автодополнение (в контексте)

    Во многих командных интерпретаторах (и в bash в том числе) используется такая возможность, как автодополнение. Как минимум нужно знать, что по нажатию клавиши Tab дописывается название команды. В bash по умолчанию обычно настроено так, что если имеется только один вариант дополнения, то он дописывается по нажатию Tab (также можно использовать Ctrl-i и Esc-Esc). Когда вариантов дополнения много, то по первому нажатию Tab дописывается только общая часть (если она есть). А по второму нажатию Tab отображается список всех доступных вариантов. Дальше можно набрать еще символов – уточнить, какое из дополнений нужно, и снова нажать Tab. То же самое с другими дополнениями: имен файлов, имен переменных.

    [00:39:20]
    [00:39:20]

    ^^^ Здесь, например, смотрю (нажав дважды Tab), что есть несколько команд, начинающихся с «if», добавив «c» и нажав Tab, получаю набранной команду «ifconfig».

    [00:39:31]
    [00:39:31]

    ^^^ В этом примере дополняю аргументы команды (здесь имена файлов). Также видно, что в случае, когда вариантов много и все не умещаются в окне терминала, их список отображается утилитой для постраничного просмотра (также при очень большом списке вариантов выдается запрос вида «Display all 125 possibilities? (y or n)» или, как в этом примере, при малом количестве - «--More--».

    Дополнения имен пользователей, переменных

    Часто, когда дописываются аргументы команд по Tab, дописываются имена файлов. Но стоит также отметить, что, в зависимости от контекста, по Tab дописываются и имена переменных (аргументы, начинающиеся с символа «$»), имена пользователей (аргументы, начинающиеся с символа «~»),…

    [00:40:36]
    [00:40:36]

    ^^^ Здесь, чтобы набрать «$HISTFILESIZE», вместо 13 символов набрал 8 символов ($ H I Tab F Tab S Tab). Помимо того, что так быстрее, это еще и позволяет допускать меньше ошибок при наборе команд, так как не просто печатаю текст, а выбираю из списка установленных переменных.

    [00:41:44]
    [00:41:44]

    ^^^ Здесь дописываю имена пользователей (фактически пишу адрес домашней директории).

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

    Список того, что может дополнять bash, можно посмотреть командой:

    ♯ bind -P | grep "complet"
    possible-username-completions can be found on "\C-x~".
    complete-username can be found on "\e~".
    possible-hostname-completions can be found on "\C-x@".
    complete-hostname can be found on "\e@".
    possible-variable-completions can be found on "\C-x$".
    complete-variable can be found on "\e$".
    possible-command-completions can be found on "\C-x!".
    complete-command can be found on "\e!".
    possible-filename-completions can be found on "\C-x/".
    complete-filename can be found on "\e/".
    [00:43:50]
    [00:43:50]

    Так, например, видно, что:

    • Ctrl-x ~ – покажет список имен пользователей, начинающихся с набранных символов, а дополнить комбинацией Esc-~;

    • Ctrl-x @ – список имен машин (согласно /etc/hosts), начинающихся с набранных символов, а дополнить – Esc-@;

    • Ctrl-x $ – список имен переменных, заданных в этой сессии (можно их также посмотреть командой set), а дополнить – Esc-$;

    • Ctrl-x ! – список команд (согласно доступных: $PATH, alias, функций, встроенных команд), а дополнить – Esc-!;

    • Ctrl-x / – список имен файлов, а дополнить – Esc-/.

    Alt-* – вставить дополнения, Ctrl-x * – развернуть шаблон

    Esc-* (точнее, Esc Shift 8) или, что, то же самое, Alt-* (точнее, Alt, Shift, 8), вставит все варианты дополнения в командную строку. Аналогично можно развернуть список файлов, переменных, имен пользователей.

    В примерах ниже разворачиваю список файлов:

    Вариант с Alt-*:

    [00:44:55]
    [00:44:55]

    Вариант с Esc-*:

    [00:46:30]
    [00:46:30]
    ♯ bind -P | grep '*'
    insert-completions can be found on "\e*".
    glob-expand-word can be found on "\C-x*".

    Ctrl-x * – развернет уже написанный в командной строке шаблон, как в примере ниже:

    [00:48:39]
    [00:48:39]

    Редактирование

    Ctrl-w/u/k – вырезать слово/начало/конец строки

    Ctrl-w – вырезать слово (от текущего положения курсора до ближайшего ранее в строке пробела/табуляции). Вырезанное можно затем вставить комбинацией Ctrl-y.

    [00:52:52]
    [00:52:52]

    Ctrl-u – вырезать начало строки (от текущего положения курсора. Если курсор в конце строки, то вырежет целиком строку). Вырезанное можно затем вставить комбинацией Ctrl-y.

    Ctrl-k – вырезать конец строки (от текущего положения курсора. Если курсор в начале строки, то вырежет целиком строку). Вырезанное можно затем вставить комбинацией Ctrl-y.

    Ctrl-y – вставить вырезанное

    Ctrl-y – вставить вырезанный фрагмент командной строки. (В bash используется свой буфер для хранения вырезанных фрагментов – называется «kill ring»).

    Важно: Удобно использовать с Alt-y (позволяет «прокручивать» варианты вставки из буфера).

    Ctrl-x Ctrl-e – редактировать в $EDITOR

    Нажав комбинацию Ctrl-x Ctrl-e, можно редактировать командную строку в любом внешнем редакторе (по умолчанию часто используется редактор vim; переназначить редактор можно, указав в переменной EDITOR). Часто редакторы имеют больше продвинутых возможностей в редактировании текста. Особенно удобно, если редактор умеет подкрашивать синтаксис команд и имеет различные встроенные инструменты для быстрого поиска и исправления ошибок.

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

    [00:53:40]
    [00:53:40]

    Ctrl-_ – undo

    Ctrl-_ (точнее, нужно нажать Ctrl Shift -) или Ctrl-x Ctrl-u – отменяет последние правки при редактировании командной строки.

    Перемещение

    Ctrl-a/e – в начало/конец строки

    Ctrl-a и Ctrl-e – перемещение в начало и конец командной строки соответственно. Можно, конечно, пользоваться клавишами Home и End, но так быстрее при использовании, например, таких клавиш, как вырезание Ctrl-w и вставка Ctrl-y.

    [00:52:05]
    [00:52:05]

    Alt-b/f и Ctrl-←/→ – предыдущее/следующие слово

    Alt-b (и тот же эффект у Ctrl-Left) – переход в начало предыдущего слова.

    Alt-f (и тот же эффект у Ctrl-Right) – переход в конец следующего слова.

    [00:50:10]
    [00:50:10]

    Настройки

    bash

    Подробнее значения действия редактирования командной строки bash можно посмотреть в мануал по bash'у. Действия, упомянутые в этой статье (в порядке упоминания):

    ♯ man bash
    • clear-screen (C-l) Clear the screen, then redraw the current line, leaving the current line at the top of the screen.

    • reverse-search-history (C-r) Search backward starting at the current line and moving `up' through the history as necessary. This is an incremental search.

    • reverse-search-history (C-r) Search backward starting at the current line and moving `up' through the history as necessary. This is an incremental search.

    • history-search-backward Search backward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search.

    • history-search-forward Search forward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search.

    • yank-last-arg (M-., M-_) Insert the last argument to the previous command (the last word of the previous history entry). With a numeric argument, behave exactly like yank-nth-arg. Successive calls to yank-last-arg move back through the history list, inserting the last word (or the word specified by the argument to the first call) of each line in turn. Any numeric argument supplied to these successive calls determines the direction to move through the history. A negative argument switches the direction through the history (back or forward). The history expansion facilities are used to extract the last word, as if the "!$" history expansion had been specified.

    • digit-argument (M-0, M-1, ..., M--) Add this digit to the argument already accumulating, or start a new argument. M-- starts a negative argument.

    • insert-comment (M-#) Without a numeric argument, the value of the readline comment-begin variable is inserted at the beginning of the current line. ... The default value of comment-begin causes this command to make the current line a shell comment.

    • operate-and-get-next (C-o) Accept the current line for execution and fetch the next line relative to the current line from the history for editing. A numeric argument, if supplied, specifies the history entry to use instead of the current line.

    • complete (TAB) Attempt to perform completion on the text before point. Bash attempts completion treating the text as a variable (if the text begins with $), username (if the text begins with ~), hostname (if the text begins with @), or command (including aliases and functions) in turn. If none of these produces a match, filename completion is attempted.

    • complete-username (M-~) Attempt completion on the text before point, treating it as a username.

    • possible-username-completions (C-x ~) List the possible completions of the text before point, treating it as a username.

    • complete-hostname (M-@) Attempt completion on the text before point, treating it as a hostname.

    • possible-hostname-completions (C-x @) List the possible completions of the text before point, treating it as a hostname.

    • complete-variable (M-$) Attempt completion on the text before point, treating it as a shell variable.

    • possible-variable-completions (C-x $) List the possible completions of the text before point, treating it as a shell variable.

    • complete-command (M-!) Attempt completion on the text before point, treating it as a command name. Command completion attempts to match the text against aliases, reserved words, shell functions, shell builtins, and finally executable filenames, in that order.

    • possible-command-completions (C-x !) List the possible completions of the text before point, treating it as a command name.

    • complete-filename (M-/) Attempt filename completion on the text before point.

    • possible-filename-completions (C-x /) List the possible completions of the text before point, treating it as a filename.

    • insert-completions (M-*) Insert all completions of the text before point that would have been generated by possible-completions.

    • glob-expand-word (C-x *) The word before point is treated as a pattern for pathname expansion, and the list of matching filenames is inserted, replacing the word. If a numeric argument is supplied, an asterisk is appended before pathname expansion.

    • unix-word-rubout (C-w) Kill the word behind point, using white space as a word boundary. The killed text is saved on the kill-ring.

    • unix-line-discard (C-u) Kill backward from point to the beginning of the line. The killed text is saved on the kill-ring.

    • kill-line (C-k) Kill the text from point to the end of the line.

    • yank (C-y) Yank the top of the kill ring into the buffer at point.

    • yank-pop (M-y) Rotate the kill ring, and yank the new top. Only works following yank or yank-pop.

    • undo (C-_, C-x C-u) Incremental undo, separately remembered for each line.

    • backward-word (M-b) Move back to the start of the current or previous word. Words are composed of alphanumeric characters (letters and digits).

    • forward-word (M-f) Move forward to the end of the next word. Words are composed of alphanumeric characters (letters and digits).

    bind -P

    Можно посмотреть, какие клавиши к каким действиям редактирования командной строки bash привязаны – для этого можно воспользоваться командой «bind -P».

    Есть и много других интересных комбинаций – для примера можно глянуть:

    Клавиши, переключающие регистр букв:
    bind -P | egrep "case|capitalize"

    [00:58:35]
    [00:58:35]

    Клавиши, меняющие слова/буквы местами:
    bind -p | grep "transpose"

    Также можно настроить свои привязки – например, чтобы по комбинации «Ctrl-f» выводился результат команды «date»:

    bind -x'"\C-f": date'

    [01:00:50]
    [01:00:50]

    /etc/inputrc (настройки библиотеки readline)

    Так как bash и многие shell'ы используют библиотеку readline для взаимодействия с командной строкой, то можно перенастроить соответствия комбинаций клавиш и действий в /etc/inputrc.

    Например, такие строки меняют поведение по умолчанию клавиш «Вверх» и «Вниз»

    ... вместо предыдущей/последующей команды они будут включать поиск по истории команд – очень удобно, часто этим пользуюсь:

    "\e[A": history-search-backward
    "\e[B": history-search-forward

    Коды клавиш можно посмотреть, используя комбинацию Ctrl-v, упомянутую выше в этой статье.

    Итог

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

    Если, по вашему мнению, стоило упомянуть какие-то еще полезные комбинации - напишите в комментариях.


    На этом всё. Надеюсь, было полезно. Если есть какие-то вопросы и уточнения, пишите, я буду рад ответить. Также буду рад упоминаниям в комментариях, что для вас оказалось полезным/новым в этой статье. Так я пойму, что стоило упоминать, а что можно было и пропустить.

    Ну, и приходите к нам учиться в «Сетевую Академию ЛАНИТ»!

    P.S. Также рекомендую к прочтению мою предыдущую Habr-статью:
    Как устроена графика в Linux: обзор различных сред оформления рабочего стола.


    А в завершение конкурс «для внимательных зрителей».

    Кто первым правильно напишет в комментариях ответ на три вопроса, получит 25% скидку на курс по написанию Bash-скриптов:

    1. Дата, когда проходил вебинар «Сетевой Академии ЛАНИТ» по теме этой статьи.

    2. Какой пароль у пользователя root на системе, используемой на вебинаре?

    3. Какой дистрибутив Линукс использовался?

    ГК ЛАНИТ
    Ведущая многопрофильная группа ИТ-компаний в РФ

    Comments 63

      +3
      Спасибо за pgUp/pgDown, не знал, что можно листать ими команды.
        +2
        На здоровье)

        К PgUp/PgDown сильно привык, так что когда пользуюсь некоторыми дистрибутивах, в которых они отключены (не прописаны в /etc/inputrc), одно из первых действий лезу добавить их обратно в /etc/inputrc
          +1
          А я всегда Alt+f/b и PgUp/PgDown меняю в .inputrc на
          "\e[A":history-search-backward # up
          "\e[B":history-search-forward # down
          "\e[1;5C": forward-word # ctrl + right
          "\e[1;5D": backward-word # ctrl + left
          0
          можно ещё набрать history — выдаст весь список ранее вводившихся команд
          затем вводите восклицательный знак и номер нужной команды — она выполняется

          часто в настройках шелла сразу делают для history алиас на букву h (чтобы не вводить всё слово)
            +3
            Верно, еще "!!" — это последняя команда и многие любят использовать команду:
             sudo !!
              +1
              У меня по Ctrl-R привязана функция с использованием команды percol — получился типа менюобразного контекстного поиска
                +2

                Ущу удобно


                history
                !123 # потом нажимаем ctrl+alt+e и !123 раскрывается в команду которую можно редактировать
              +4
              нет никакой фразы (типа «Горшочек, не вари»), которую бы команда cat восприняла как «окончание ввода»

              Если хочется, то можно и так (конечно, это сама оболочка распарсит, а не cat):


              cat << 'Горшочек, не вари' > helloworld.txt
              Привет, мир!
              И тебе привет.
              Горшочек, не вари

              В отличие от Ctrl+D можно использовать в скриптах.

                +4
                Улыбнуло использование фразы из текста)

                да, верно — есть у bash'а(не у cat) такая возможность — «Here Documents» называется (в «man bash»).

                Еще можно с табами использовать (в скриптах удобно), если написать "<<-":
                cat <<- 'Горшочек, не вари' > helloworld.txt
                    Привет, мир!
                    И тебе привет.
                Горшочек, не вари
                +2
                Обидно только, что многие терминалы не уважают многие хоткеи
                  0
                  Спасибо! Ссылку на страничку отправил в поминальник. И себе, и буду делиться с новичками.
                    +4

                    Мне удобнее использовать Up/Down для листания истории с учётом начала команды. И Tab без учёта регистра. Поэтому всегда первым делом правлю .inputrc:


                    "\e[A": history-search-backward
                    "\e[B": history-search-forward
                    "\e\e": kill-whole-line
                    
                    set colored-stats On
                    set completion-ignore-case On
                    set completion-prefix-display-length 3
                    set mark-symlinked-directories On
                    set show-all-if-ambiguous On
                    set show-all-if-unmodified On
                    set visible-stats On

                    Как без этого жить вообще?

                      +3
                      Полезно.

                      Судя по «man readline»:
                      • set colored-stats On — подкрашивать автодополняемые имена цветом как и ls
                      • set completion-ignore-case On — тут понятно, игнорировать регистр при дополнении
                      • set completion-prefix-display-length 3 — как понял, общую часть дополнения при отображении схлопывает до "___"
                      • set mark-symlinked-directories On — помечает дириктории-симлинки "@" — удобно при включеной colored-stats
                      • set show-all-if-ambiguous On — начинает отображать возможные автодополнения по первому Tab'у
                      • set show-all-if-unmodified On — не понял отличие от предыдущего параметра
                      • set visible-stats On — должно(у меня не сработало) отображать информацию о файлах в автодополнении
                        0

                        Я так давно читал man readline и задавал эти опции, что уже и сам забыл, что некоторые из них значат. Спасибо, что не поленились сделать summary. Хоть перечитал.


                        show-all-if-ambiguous
                        This alters the default behavior of the completion functions. If set to ‘on’, words which have more than one possible completion cause the matches to be listed immediately instead of ringing the bell. The default value is ‘off’.
                        
                        show-all-if-unmodified
                        This alters the default behavior of the completion functions in a fashion similar to show-all-if-ambiguous. If set to ‘on’, words which have more than one possible completion without any possible partial completion (the possible completions don’t share a common prefix) cause the matches to be listed immediately instead of ringing the bell. The default value is ‘off’.
                        
                        visible-stats
                        If set to ‘on’, a character denoting a file’s type is appended to the filename when listing possible completions. The default is ‘off’.

                        Проверил set visible-stats on, у меня тоже ничего не меняет.

                          +2
                          Проверил set visible-stats on, у меня тоже ничего не меняет.

                          Тоже сразу не понял на что оно влияет.
                          Наглядно видно если ввести ping<tab> с включенной опцией:


                          ping*  ping4@ ping6@

                          и с выключенной:


                          ping   ping4  ping6

                          ping4 и ping6 это симлинки, оно их помечает @
                          ping исполняемый, помечен *

                          +1
                          set completion-prefix-display-length 3 — как понял, общую часть дополнения при отображении схлопывает до "___"

                          «Схлопывает» до многоточия.
                          www.gnu.org/software/bash/manual/html_node/Readline-Init-File-Syntax.html
                          Толковые примеры:
                          www.reddit.com/r/commandline/comments/kbeoe/you_can_make_readline_and_bash_much_more_user
                        0
                        Яркий пример архаизма в линуксе это вот такие странные комбинации. Ещё Ctrl-S и Ctrl-Q которые выполняют тот же функционал, что должна выполнять клавиша ScrollLock, но почему-то не выполняет.
                        Благо в современных терминалах работают более человеческие комбинации, хотя местами тоже странные: например перемещаться по словам можно по Ctrl-стрелки, но удалять по словам: Alt-Backspace
                          +7
                          Пользователи Емакса радуются хоткеям в шелле потому что они им как родные. В прямом смысле: sh и bash используют те же хоткеи что и Емакс.

                          Впрочем, команда set -o vi позволит переключится в режим ввода «как в vi». Собственно, у вас как в vi будет два режима: режим команд и режим редактирования. set -o emacs переключит ввод обратно, если что.

                          И еще. Meta — это не Alt. Meta — это Meta. Просто Emacs разрабатывали под вот такие клавиатуры:

                          image

                          На современных клавиатурах таких кнопок конечно же нет, поэтому приходится использовать Alt вместо Meta и Win вместо Super.
                            +1
                            Да — всё верно.

                            Только похоже многие(так кажется) часто сначала изучают командную строку и привыкают к этим emacs-клавишам, а потом (сильно не сразу) изучают vi — в итоге (как и я) знают vi и не пользуюсь emacs, но к этим хоткеям уже попривыкли.
                              +1

                              Использую не bash, но fish. На самом деле, режим vi почти не конфликтует с режимом Emacs, поэтому, например, в fish с небольшими кастомизациями можно использовать оба одновременно (по умолчанию включен режим Insert, в котором работают основные клавиши Emacs). Мои дополнения для режима vi:


                              function fish_user_key_bindings                                                                                                                                                                                                                                                             
                                  fish_vi_key_bindings                                                                                                                                                                                                                                                                    
                                  bind \cr reverse_history_search                                                                                                                                                                                                                                                         
                                  bind -M insert \cr reverse_history_search                                                                                                                                                                                                                                               
                                  bind -M insert \cf forward-char                                                                                                                                                                                                                                                         
                                  bind -M insert \cA beginning-of-line                                                                                                                                                                                                                                                    
                                  bind -M insert \cE end-of-line                                                                                                                                                                                                                                                          
                              end

                              У режима vi есть другой недостаток: не знаю как в bash (полагаю, что так же, т.к. наверняка используется тот же readline), а в fish некоторые команды vi работают чуточку не так, как в редакторе: останавливаются на символе раньше или символе позже, например. Это делает работу довольно некомфортной, т.к. всё время приходится контролировать, что происходит после нажатия кнопок, тогда как в редакторе можешь уже на автомате стрелять сочетаниями в 4-5 клавиш, не беспокоясь о результате.

                              +2
                              Именно так, а всё потому что ввод обрабатывалется с помощью библиотеки 'readline'.
                              Я первым делом после прочтения заголовка статьи отправился искать 'emacs'.

                              LinuxCertifiedInstructor
                              Написать целое полотно по использованию Emacs-like команд в Bash и при этом не указать откуда это пришло (а заодно не указать про существование vim-mode, и, соответственно совершенно иного поведения shell), имхо не достойно уровня сертифицированного инструктора по линуксу. Исправьте.

                              Edit.
                              Особенно в разрезе вашего предыдущего комментария про vim/emacs. Если это матерьял для новичков, то я считаю особенно важным с ходу обьяснить что к чему. И может даже посоветовать попробовать vim-mode.
                                +2
                                Что за мания про комменты «достойно-недостойно уровня инструктора»?)…
                                Скажу по секрету не в одной сертификации (которые знаю и сдавал. Если знаете такую напишите название) не на уровень специалиста, ни на преподавателя не спрашивают про vim-mode в командной строке bash.

                                Новички обычно на этой теме не знают про vim, и до конца курса могут и не услышать совсем про emacs (извините фанаты emacs, но так часто происходит — ну есть что другое изучить на курсе вместо этого) — количество дней ограничено чтобы рассказать абсолютно всё и по каждому вопросу еще и экскурс в истории провести… тут скорее если вопрос из зала подтолкнет к этой теме.

                                Но соглашусь в статью стоит добавить
                                  0
                                  Что за мания про комменты «достойно-недостойно уровня инструктора»?)…

                                  Рискну предложить что «сертификат», это лишь бумажка подтверждающая что вы умеете выучить правильные ответы на конкретные вопросы, а реально стоящий инструктор/лектор вам покажет что, зачем и почему.
                                  Сам сдавал сертификационные экзамены, среди которых были и Juniper/RedHat/Amazon. Прекрасно знаю насколько они «ниочём» с точки зрения применения реальных знаний в реальной ситуации если не понимаешь откуда ноги растут.

                                  Новички обычно на этой теме не знают про vim, и до конца курса могут и не услышать совсем про emacs

                                  Это и считаю упущением. Может это просто я такой, но я предпочитаю когда мне вместе с каким-то знанием той или иной вещи обьясняют «почему так» — с историей происхождения, если таковая имеется.

                                  Приведу пример — '\n' как обозначение конца файла.
                                  Мало того что куча людей до конца не понимает разницу между '\n' и «новой строкой», так ещё даже ярые защитники POSIX стандарта не всегда знают откуда это взялось и не думают на тему того, нужно-ли это повсеместно применять на проекте, где нет ни одного исходника Си или Makefile, кроме как в угоду POSIX совместимости.
                                    +1
                                    Сертификат ни то чтобы совсем «ни о чем», скорее как раз их цель проверить наличие реальных знаний, хотя получается скорее поверхностно оценить.

                                    Ладно, забили — а то будем бесконечно обоюдно хвалится знаниями.
                                    Были б курсы по месяцу, а лучше полгода… вот тогда бы… эх.
                            0
                            Класс, всегда полезно вспомнить. Но, set -o vi и установка FZF помогают частично упростить работу в строке.
                              +4

                              Оформление материала офигенное, респект!


                              Но вот структура… Хоткеи консоли (tty) перепутаны с readline и собственными эвристиками баша… С точки зрения моторики это не важно, с точки зрения стройной картины в голове — очень важно.

                                +1
                                Спасибо (про оформление)

                                (Про структуру) Что не на своем месте? Поправьте.
                                  +5

                                  Ну, смотрите, правильно было бы объяснять откуда что приходит.


                                  Уровень первый: терминал. Нажимаете вот эти кнопки, их терминал преобразует в ioctl для лидера сесссии (или как он преобразует? Я вот не знаю).


                                  Следующий уровень: readline. Кто использует, как обрабатывает. Кнопки.


                                  Следующий уровень: приятности баша.


                                  Потому что из вашего описания мне трудно понять, кто именно обрабатывает, например, ctrl-r. Это readline или баш? А ещё я могу нажать Crtl-Shift-u,3344,Enter и получить на экране вот это: "㍄". Так что X'ы тут тоже надо упомянуть. Включая keymap и compose.

                                    0
                                    Понятно, просто изначально статья была про полезные клавиши знание которых полезно при работе в командной строке — такой «Необходимый минимум по работе в командной строке», которые я далее сгруппировал по тема «Редактирование, Перемещение,...». Про readline, bash, stty было совсем не основное, оно всплыло только чтобы объяснить почему в каком-нибудь другом дистрибутиве, отличном от мною используемом, какие-нибудь клавиши заработают не так.

                                    Про графику кстати упомянул.
                                    Сам всегда пользовался и xmodmap и sxhkd — но это уж лишнее для этой темы
                                +4
                                Первые две комбинации клавиш достаточно важные, и часто «недавно перешедшие с Windows на Linux» НЕправильно их используют: продолжая, как в DOS, для завершения команд использовать комбинацию «Ctrl-z», что неверно. В Linux же для того, чтобы попросить (команде посылается сигнал SIGINT) приложение прервать свою работу, используется Ctrl-c.
                                Вообще-то в DOS (и консоли Windows) назначение Ctrl-C ровно то же, что и в *nix. А вот Ctrl-Z — это аналог никсового Ctrl-D.
                                  +1
                                  Забавно если «Ctrl-с» в Windows по разному трактуется (или трактовался в каких-то версиях) в консоли и в графике. Ну вполне вероятно могу в том что касается Windows ошибаться — всё так почти совсем её лет 15 как не использую.
                                    0
                                    А что, в линуксе не по-разному, что ли?
                                      +1
                                      по разному.
                                      Но в Линуксе мне эти отличия более понятны — всё ж разные группы людей в разное время делали разные части системы.
                                        0
                                        Как будто в винде не разные.
                                        Да что о gui говорить — много ли приложений на ncurses, в которых Ctrl-C их завершает?
                                  +1

                                  Спасибо за Alt+#! Осталось отучиться от Ctrl+a # Enter

                                    +2
                                    Знает ли кто-нибудь, как бороться с проблемой, что иногда командная строка bash отображается с некоторым «смещением», так что видимые правки не совпадают с реальными?
                                    Простое нажатие Enter исправляет проблему, но для этого надо успеть понять, что текущая строка «битая» (например, это можно проверить нажатием Home — признаком будет то, что курсор окажется на пару символов сдвинутым относительно ожидаемой позиции).

                                    P.S. Понимаю, что это оффтоп, но это косвенно связано с темой статьи, т.к. необходимость постоянно держать в голове эту потенциальную проблему «убивает» производительность.
                                      +1
                                      ctrl-L в подобной ситуации должно помочь
                                        +2
                                        предположу (почти уверен), что проблема в том что в приглашении используете последовательности для, например, подкраски цветами приглашения и не «экранируете» их (обрамить в "\[" и "\]") — и в итоге bash (или терминал) эти символы цвета воспринимает как символы и считает их при переносе строк, хотя и не отображает их терминал.

                                        То есть неправильно (будет с смещением) делать приглашение так:
                                        PS1="\e[7;32m>>>\e[0m "

                                        а правильнее так (будет без смещения):
                                        PS1="\[\e[7;32m\]>>>\[\e[0m\] "
                                        0

                                        иногда терминал "ломается", помогает stty sane

                                          +2
                                          при выводе некоторых непечатных управляющих символов терминал «ломается» — починить можно «stty sane» или «reset» (причем набирая не смотря на отображаемые символы-крокозябры и нажать «Enter»)
                                            0

                                            stty sane у меня всегда шёл в паре с setterm reset в 99 процентах случаев помогает.

                                          0

                                          хозяйке на заметку, ctrl-d как окончание файла, но не просто, а только на новой строке, то есть


                                          текст
                                          ххххх
                                          <enter> ctrl-d

                                          если не хочется заканчивать текст новой строкой, можно дважды нажать ctrl-d


                                          текст
                                          ххх ctrl-d ctrl-d
                                            0
                                            Кроме Ctrl-w/u/k есть еще Alt-d — удалить вперед до конца слова. Непонятно только почему она с Alt, когда все остальные с Ctrl.
                                              +1

                                              Не читал все комменты, если не написали, то в bash есть опция," set -of vi" Если привыкли к vim, то в bash е будет очень удобно, поиск по бэк слешу, история n или N undo, redo как в vim, единственное, если переходите в визуальный режим, то открывается vim, а в нём нет автодополнений bash

                                                0

                                                одно из самых "спасающих" сочетаний это ctrl-y
                                                все удаления текста, по сочетаниям клавиш (кроме Backspace/Del) можно восстановить взад.
                                                то есть например:


                                                $ echo test <alt-Backspace>

                                                даёт


                                                $ echo 

                                                последущее нажатие ctrl-y восстанавливает все обратно в


                                                echo test
                                                  0
                                                  Тут лучше:
                                                  Ctrl-_ (точнее, нужно нажать Ctrl Shift -) или Ctrl-x Ctrl-u – отменяет последние правки при редактировании командной строки.


                                                  а «Ctrl-y» не отмена удаления, а «вставить вырезанное» и очень удобно использовать с Alt-y (позволяет «прокручивать» варианты вставки из буфера).
                                                    0

                                                    ctrl-x ctrl-u это что то новое, никогда не пользовался, прикольно.


                                                    Не думаю что запомню, но сам факт, что оно там где то есть и его можно найти :)


                                                    и да, конечно ctrl-y это вставка удалённого

                                                    0

                                                    Если не ошибаюсь, то при "set -o vi" подобное поведение достигается нажатием клавиш dw (удалить "test") далее u (восстановит "test")

                                                      0
                                                      скорее тут подобно сделает — "db" (удалит от текущего положения курсора до предыдущего знака пунктуации),
                                                      а "dw" — удалит до начала следующего слова.

                                                      А «u» — верно, отменить предыдущую правку, то есть здесь воcстановит «test»
                                                      Ну или, тот же результат, «p» — вставит вырезанное при помощи db или dw
                                                    +2
                                                    А если отключить xon/xoff (stty -ixon), то можно наряду с ctrl+r использовать ctrl+s для поиска вперед.
                                                    Удобно когда при обратном поиске случайно пролистаешь команду, то можно вернуться.
                                                      0
                                                      > Ctrl-z – сигнал SIGTSTP
                                                      кажется, и у меня в убунте и у вас на скрине, в выводе `stty -a`, ^S — это стоп а ^Z — саспенд:
                                                      stop = ^S; susp = ^Z;

                                                      Почему? Наверное, в терминах stty обозначение susp равняется сигналу TSTP? Тогда что делает ^S?

                                                      Фактически посылается TSTP по ^Z:

                                                      $ perl -E '$SIG{TSTP}=sub{ say "here is STOP"}; $SIG{INT}=sub{ say "here is INT"}; sleep 999'

                                                      ^Chere is INT

                                                      $ perl -E '$SIG{TSTP}=sub{ say "here is STOP"}; $SIG{INT}=sub{ say "here is INT"}; sleep 999'

                                                      ^Zhere is STOP
                                                        +1
                                                        Кажется, вот и ответ из man stty:
                                                        stop CHAR
                                                        CHAR will stop the output

                                                        susp CHAR
                                                        CHAR will send a terminal stop signal


                                                        Т.е. stop прекращает вывод, как-то обрубает весь stdout. Непонятно как.
                                                        А susp действительно посылает, только не stop, а tstop?
                                                          0
                                                          Спасибо за выдержку из «man stty».
                                                          Да всё верно — «Ctrl-z» посылает SIGTSTP («Stop typed at terminal» согласно «man 7 signal»), и это совсем не сигнал SIGSTOP
                                                        0
                                                        А где Ctrl+L задан?
                                                        Не видать его что-то в stty -a
                                                          0
                                                          Это в readline, который использует bash — можно в «man 1 bash» или в «man 3 readline» прочитать:
                                                          clear-screen (C-l) Clear the screen, then redraw the current line, leaving the current line at the top of the screen. With an argument, refresh the current line without clearing the screen.


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

                                                          0
                                                          ^^^ В правом терминале отображаю историю команд.

                                                          А чем Вы её там отображаете, если не секрет? Просто интересно: знаю несколько способов, но это не они.

                                                            0
                                                            tail -f ...| grep…
                                                              0
                                                              tail -n0 -f $HISTFILE | egrep --color -n "(|Нужные|слова|например|sudo)" 


                                                              Только у меня еще включена в ~/.bashrc:
                                                              shopt -s histappend
                                                              export PROMPT_COMMAND="history -a; history -c"


                                                              А какие способы знаете вы?
                                                                0

                                                                Только попсу: tail -f, less -F
                                                                Меня номера строк насторожили. А они, оказывается, извне, от грепа. За egrep спасибо, я до сих пор про него как-то не слышал, а зря.

                                                                  0
                                                                  Подскажите как вы сделали чтобы история автоматически выдавала вновь вводимые команды. Разве эти два терминала не в отдельных сессиях?
                                                                    0
                                                                    Ответ на этот вопрос в сообщении выше:
                                                                    у меня еще включена в ~/.bashrc:
                                                                    shopt -s histappend
                                                                    export PROMPT_COMMAND="history -a; history -c"


                                                                    Да в отдельных, но две указанные строки включают синхронизацию между сессиями — буквально каждая новая команда пишется в ~/.bash_history сразу же как появилось следующее приглашение командной строки. То есть «по каждому чищу» пишет на диск и считывает с диска в память текущей сессии.
                                                                0
                                                                Часто, когда дописываются аргументы команд по Tab, дописываются имена файлов. Но стоит также отметить, что, в зависимости от контекста, по Tab дописываются и имена переменных (аргументы, начинающиеся с символа «$»), имена пользователей (аргументы, начинающиеся с символа «~»)


                                                                Маленькое уточнение — не только файлов, а путей в принципе (файлы, директории, пайпы, ссылки — все что может быть в пути)

                                                                Кроме того, не только переменных, но еще и алиасов и имен функций.

                                                                Кроме того многие команды могут добавлять в bash-completion свои собственные правила для автокомплита опций, что многие и сделали (в убунту можно глянуть список тут /usr/share/bash-completion/completions), например:
                                                                chmod --h
                                                                  0
                                                                  Маленькое уточнение — не только файлов, а путей в принципе (файлы, директории, пайпы, ссылки — все что может быть в пути)
                                                                  Имеется в виду «файлов» в общем смысле, а не только регулярных, то есть как раз все 7типов какие в Линуксе используются (socket, named pipe, directory, symlink, block special file, character special file, ну и regular file).

                                                                  Кроме того, не только переменных, но еще и алиасов и имен функций.
                                                                  Согласен. (и встроенные команды в bash тоже).

                                                                  bash-completion
                                                                  Просто тут была скорее про клавиши чем про работу автодополнения — в курсе в этой теме и про команду complete пример показываю — как свои автодополнения к чему-нибудь прикрутить.
                                                                  Например (к команде rpm, автодополнение списка установленных пакетов):
                                                                  complete -W "-qi -qa -ql $(rpm -qa)" rpm

                                                                Only users with full accounts can post comments. Log in, please.