Как использовать команду History в Bash в Linux

 

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

К счастью, оболочка bash имеет довольно хорошо развитые функции истории. Научившись эффективно использовать историю bash и манипулировать ею, вы сможете тратить меньше времени на набор текста и больше времени на реальную работу. Многие разработчики знакомы с философией DRY (Don't Repeat Yourself). Эффективное использование истории bash позволит вам действовать ближе к этому принципу и ускорит ваш рабочий процесс.

Предварительные условия

Чтобы следовать этому руководству, вам потребуется доступ к компьютеру с операционной системой на базе Linux. Это может быть либо виртуальный частный сервер, к которому вы подключились с помощью SSH, либо ваша локальная машина.

Установка параметров истории по умолчанию

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

Bash позволяет настроить количество команд, которые он сохраняет в истории. На самом деле для этого есть два отдельных параметра: параметр HISTFILESIZE определяет, сколько команд будет храниться в файле истории, а HISTSIZE - количество команд, хранящихся в памяти для текущего сеанса.

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

Чтобы изменить эти параметры, откройте файл ~/.bashrc в удобном для вас текстовом редакторе. Здесь мы будем использовать nano:

Файл ~/.bashrc

Найдите параметры HISTSIZE и HISTFILESIZE. Если они установлены, смело изменяйте их значения. Если этих параметров нет в вашем файле, добавьте их сейчас. Для целей данного руководства вполне подойдет сохранение 10000 строк на диск и загрузка последних 5000 строк в память. Это консервативная оценка для большинства систем, но вы можете изменить эти значения в меньшую сторону, если заметите влияние на производительность:

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

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

Если вы хотите, чтобы bash немедленно добавлял команды в вашу историю, а не ждал окончания каждого сеанса (чтобы команды в одном терминале были мгновенно доступны в другом), вы также можете задать или добавить команду history -a к параметру PROMPT_COMMAND, который содержит команды, выполняемые перед каждым новым приглашением командной строки.

Чтобы настроить это правильно, вам нужно будет изменить PROMPT_COMMAND в bash, чтобы изменить способ записи команд в файл истории и в память текущего сеанса оболочки:

  1. Нужно немедленно добавлять в файл истории с помощью команды history -a.
  2. Затем нужно очистить текущую историю в сеансе командного интерпретатора с помощью команды history -c.
  3. Наконец, чтобы загрузить обновленную историю обратно в сеанс оболочки, используйте команду history -r.

Если собрать все эти команды по порядку в переменной PROMPT_COMMAND, то получится следующее, что вы можете вставить в свой файл .bashrc:

Когда вы закончите, сохраните файл и выйдите. Если вы редактировали свой файл .bashrc с помощью nano, сделайте это, нажав CTRL + X, Y, а затем ENTER.

Чтобы внести изменения, либо выйдите из системы и снова войдите в нее, либо создайте исходный текст файла, выполнив команду:

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

Просмотр предыдущей истории Bash

Для просмотра истории bash можно использовать команду history. Она выведет наши последние команды, по одной команде в строке. В результате будет выведено, по крайней мере, то количество строк, которое вы выбрали для переменной HISTSIZE. Вероятно, на данном этапе оно будет меньше:

history

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

Вы можете сократить вывод, указав номер после команды. Например, если вы хотите вернуть только последние 5 команд, которые были выполнены, вы можете ввести:

history 5

Чтобы найти все команды истории, содержащие определенную строку, вы можете передать результаты в команду grep, которая ищет в каждой строке заданную строку. Например, вы можете найти строки, содержащие cd, набрав:

history | grep cd

 

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

Выполнение команд из истории Bash

Печать истории команд может быть полезной, но она не поможет вам получить доступ к этим командам, кроме как в качестве ссылки.

Вы можете вспомнить и немедленно выполнить любую команду, возвращенную операцией истории, по ее номеру, которому предшествует восклицательный знак (!). Если результаты работы с историей совпадают с результатами из предыдущего раздела, вы можете быстро просмотреть страницу man для команды history, набрав:

Это немедленно вызовет и выполнит команду, связанную с номером истории 7.

Выполнение команд из истории Bash

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

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

Если вы хотите вызвать и выполнить команду, которая была запущена перед последней командой (командой ls), вы можете набрать !-2:

Выполнение команд из истории Bash

Чтобы повторно выполнить последнюю команду, вы можете набрать !-1. Однако bash предоставляет ярлык, состоящий из двух восклицательных знаков, который подставит последнюю команду и выполнит ее:

Многие используют это сочетание, когда набирают команду, но забывают, что для ее выполнения нужны привилегии sudo. Набрав sudo !!, вы повторно выполните команду с sudo перед ней:

Прокрутка истории Bash

Существует несколько способов прокрутить историю bash, помещая каждую последующую команду в командную строку для редактирования.

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

Если

  • вам нужно двигаться в другом направлении, клавиша со стрелкой вниз перемещается по истории в обратном направлении, возвращая вас к текущему пустому приглашению.
  • перемещение руки к клавишам со стрелками кажется вам слишком хлопотным, вы можете переместиться назад в истории команд с помощью комбинации CTRL + P и использовать комбинацию CTRL + N, чтобы снова переместиться вперед по истории.
  • вы хотите вернуться к текущей командной строке, вы можете сделать это, нажав META + >. В большинстве случаев "мета" - это клавиша ALT, поэтому META + > означает нажатие ALT + SHIFT + ... Это удобно, если вы оказались далеко в прошлом и хотите вернуться к пустой подсказке.

Вы также можете перейти к первой строке истории команд, выполнив обратный маневр и набрав META + <. Обычно это означает нажатие ALT + SHIFT + ,.

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

  • Клавиша со стрелкой вверх: Прокрутка истории назад
  • CTRL + P: прокрутка истории назад
  • Клавиша со стрелкой вниз: Прокрутка вперед в истории
  • CTRL + N: Прокрутка вперед в истории
  • ALT + SHIFT + ..: Перейти в конец истории (самый последний)
  • ALT + SHIFT + ,: Переход к началу истории (самое последнее)

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

Хотя передача команды history через grep может быть полезным способом сузить результаты, во многих ситуациях это не идеально.

Bash включает функцию поиска по истории. Типичный способ использования - поиск в истории в обратном порядке (самые последние результаты возвращаются первыми) с помощью комбинации клавиш CTRL + R.

Например, вы можете набрать CTRL + R и начать вводить часть предыдущей команды. Вам нужно набрать только часть команды. Если вместо нее будет введена ненужная команда, вы можете снова нажать CTRL + R для получения следующего результата.

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

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

Помните, что во многих терминалах комбинация CTRL + S используется для приостановки сеанса работы с терминалом. Это перехватит любые попытки передать CTRL + S в bash и "заморозит" ваш терминал. Чтобы разморозить сеанс, наберите CTRL + Q, чтобы отменить приостановку.

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

stty - это утилита, которая позволяет изменять настройки терминала из командной строки. Вы можете добавить эту команду stty -ixon в конец вашего файла ~/.bashrc, чтобы сделать это изменение постоянным.

Если теперь вы снова попробуете искать с помощью CTRL + S, это должно сработать, как и ожидалось, чтобы позволить вам искать вперед.

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

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

Правильный способ поиска с использованием того, что уже находится в командной строке, заключается в перемещении курсора в начало строки с помощью CTRL + A, вызове обратной истории с помощью CTRL + R, вставке текущей строки в поиск с помощью CTRL + Y, а затем повторном использовании CTRL + R для поиска в обратном направлении.

Например, предположим, вы хотите обновить кэш пакетов в системе Ubuntu. Вы уже набирали это недавно, но вспомнили об этом только после того, как снова набрали sudo в подсказке:

В этот момент вы понимаете, что эту операцию вы определенно выполняли в течение последнего дня или около того. Вы можете нажать CTRL + A, чтобы переместить курсор в начало строки. Затем нажмите CTRL + R, чтобы вызвать обратный инкрементный поиск истории. Это имеет побочный эффект копирования всего содержимого командной строки, которое было после позиции курсора, и помещения его в буфер обмена.

Затем нажмите CTRL + Y, чтобы вставить в поиск сегменты команд, которые вы только что скопировали из командной строки. И наконец, нажмите CTRL + R для перемещения назад в истории поиска команд, содержащих только что вставленное содержимое.

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

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

Знакомство с более продвинутым расширением истории

В этом руководстве уже были рассмотрены некоторые из наиболее фундаментальных методов расширения истории, которые предоставляет bash. Вот некоторые из них, которые мы уже рассмотрели:

  • !!: Расширение до последней команды
  • !n: Расширить команду с номером истории "n".
  • !-n: Развернуть до команды, которая была за "n" количество команд до текущей команды в истории.

Десигнаторы событий

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

Например, вы можете выполнить последнюю команду ssh, которую вы запускали, набрав что-то вроде:

Это позволит найти в истории команд строки, начинающиеся с ssh. Если вы хотите найти строку, которая не находится в начале команды, вы можете окружить ее символами ? Например, чтобы повторить предыдущую команду поиска apt-cache, вы можете выполнить следующую команду, чтобы найти и выполнить ее:

Еще один обозначитель событий, который можно попробовать, заключается в замене строки в последней команде на другую. Для этого введите символ каретки (^), за которым следует строка, которую вы хотите заменить, затем сразу за ним еще одну каретку, заменяющую строку и последнюю каретку в конце. Не включайте пробелы, если они не являются частью строки, которую вы хотите заменить, или частью строки, которую вы хотите использовать в качестве замены:

Это вызовет предыдущую команду (так же, как !!), найдет в строке команды экземпляр original и заменит его на replacement. Затем команда будет выполнена с использованием строки-заменителя.

Это полезно для решения таких проблем, как опечатки. Например, допустим, вы по ошибке выполнили эту команду при попытке прочитать содержимое файла /etc/hosts:

Вывод
cat: /etc/hosst: Нет такого файла или каталога

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

Это исправит ошибку в предыдущей команде и выполнит ее успешно.

Десигнаторы событий

Словесные обозначения

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

Для этого команда делится на "слова", которые определяются как любой фрагмент, разделенный пробелами. Это позволяет использовать некоторые интересные возможности для взаимодействия с параметрами команды.

Нумерация слов начинается с начальной команды как "0", первого аргумента как "1" и продолжается далее.

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

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

Это будет действовать точно так же.

Вы можете обозначить первый аргумент косым знаком (^), а последний аргумент - знаком доллара ($), если это имеет смысл для ваших целей. Это более полезно при использовании диапазонов вместо конкретных чисел. Например, у вас есть три способа получить все аргументы из предыдущей команды в новую команду:

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

Модификаторы

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

Например, вы можете отрезать путь к файлу с помощью модификатора h (он означает "голова"), который удаляет путь до последнего символа косой черты (/). Имейте в виду, что это не будет работать так, как вам нужно, если вы используете это для усечения пути к каталогу, а путь заканчивается косой чертой.

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

Например, выполните эту команду, чтобы вывести на экран содержимое лицензии на программное обеспечение с открытым исходным кодом:

Убедившись, что лицензия подходит для ваших нужд, вы можете захотеть перейти в каталог, где она хранится. Это можно сделать, вызвав команду cd по цепочке аргументов и отрезав имя файла в конце:

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

Вывод

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

Для этого вы можете выполнить обратную предыдущей манипуляцию, отрезав путь и используя только имя файла с модификатором t, который означает "tail". Вы можете найти последнюю операцию cat и использовать флаг t для передачи только имени файла:

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

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

Если ваш tarball использует расширение tar.gz вместо tgz, вы можете просто передать модификатор дважды:

Аналогичный модификатор, e, удаляет все, кроме идущего в конце расширения.

Если вы не хотите выполнять команду, которую вспоминаете, а хотите только найти ее, вы можете использовать модификатор p, чтобы bash повторил команду вместо ее выполнения.

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

Например, представьте, что вы запустили команду find в своем домашнем каталоге, а затем поняли, что хотели запустить ее из корневого каталога (/). Вы можете проверить правильность замен следующим образом (при условии, что исходная команда связана с номером 119 в вашей истории):

Выход

Если полученная команда верна, вы можете выполнить ее с помощью комбинации клавиш CTRL + P.

Вы также можете сделать замену в команде, используя синтаксис s/original/new/.

Например, вы могли бы сделать это, набрав:

Это заменит первый экземпляр шаблона поиска (~).

Вы можете заменить каждое совпадение, передав вместе с s флаг g. Например, если вы хотите создать файлы с именами file1, file2 и file3, а затем создать каталоги dir1, dir2, dir3, вы можете сделать следующее:

Конечно, более интуитивно понятным в этом случае может быть просто выполнить mkdir dir1 dir2 dir3. Однако, освоив использование модификаторов и других инструментов расширения истории bash, вы сможете значительно расширить свои возможности и производительность работы в командной строке.

Заключение

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

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

Понравилась статья? Поделиться с друзьями:
Добавить комментарий