🐧 Как управлять историей Bash

Мануал

BASH (Bourne Again SHell) – это оболочка по умолчанию практически во всех операционных системах на базе Linux.

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

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

Где хранится история BASH?

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

Задумывались ли вы когда-нибудь, где и как сохраняется история Bash?

Список команд, которые мы вызываем в оболочке Bash, хранится в так называемом “history file”, который по умолчанию находится в ~/.bash_profile.

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

Работа со встроенной командой “history”

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

Каждая строка в выдаваемом ею выводе имеет префикс в виде номера:

$ history
    1  echo "itsecforu.ru"
    2  cat /etc/hostname
    3  ls -l /etc/hostname
    4  history

Очистка истории оболочки Bash

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

Например, чтобы очистить всю текущую историю оболочки Bash, достаточно вызвать ее с опцией -c.

У нас также есть возможность удалить конкретную команду из истории, используя опцию -d и передавая в качестве аргумента смещение строки.

Представьте, что мы хотим удалить строку 1 из текущей истории в памяти.

Мы вызываем команду history следующим образом:

$ history -d 1

В качестве смещения можно использовать отрицательные числа: в этом случае подсчет строк начнется с конца списка.

Передача -1 в качестве смещения в опцию -d, например, приведет к удалению последней строки истории.

При выполнении такой операции, однако, следует учитывать одно обстоятельство: удаление произойдет после того, как команда history -d будет добавлена к самому списку, поэтому для удаления третьей строки с конца истории мы должны фактически выполнить history -d -4.

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

Это можно сделать, работая с переменными HISTCONTROL или HISTIGNORE: мы увидим, как это сделать.

Запись истории в файл вручную

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

Что если мы хотим заставить историю в памяти записываться в определенное время?

И снова мы можем использовать команду history для выполнения этого действия.

На этот раз мы должны вызвать ее с опцией -w, которая не принимает никаких аргументов:

$ history -w

Изменение поведения истории с помощью переменных окружения

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

Рассмотрим некоторые примеры.

Переменная HISTCONTROL

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

Эта переменная принимает разделенный двоеточием “список” значений, которые влияют на включение команд в историю.

В большинстве дистрибутивов ее значение по умолчанию – просто ignoredups:

$ echo $HISTCONTROL
ignoredups

Что это значит?

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

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

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

Давайте обновим значение переменной на лету и проверим, что это работает:

$ HISTCONTROL="ignoredups:ignorespace"
$  echo "this command will not be included in the history"
"this command will not be included in the history"
$  history
    1  HISTCONTROL="ignoredups:ignorespace"

Ранее уже рассмотрели это подробно:

🐧 Как избежать повторяющихся записей в истории Bash Linux

Переменная HISTIGNORE

Как и переменная HISTCONTROL, HISTIGNORE принимает в качестве значения список элементов, разделенных двоеточием, но она используется для указания команд, которые должны быть исключены из истории оболочки.

Рассмотрим пример: предположим, мы хотим исключить команды ls и history из истории оболочки.

Вот значение, которое мы присвоим переменной HISTIGNORE:

$ HISTIGNORE="ls:history"
$ echo "this will be included in history"
"this will be included in history"
$ ls
file.txt
$ history
    1  echo "this will be included in history"

Как вы можете заметить, после изменения значения, присвоенного переменной HISTIGNORE, мы просто выдали эхо-сообщение, затем выполнили команды ls и history.

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

Однако следует заметить одну вещь: исключена будет только та команда, которую мы укажем в HISTIGNORE.

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

$ HISTIGNORE="ls:history"
$ echo "this will be included in history"
"this will be included in history"
$ ls -l
-rw-rw-r--. 1 egdoc egdoc    0 Jan  7 11:51 file.txt
$ history
    1  echo "This ill be included in history"
    2  ls -l

Как избежать этого? Мы можем просто использовать * (glob) в качестве части указанной команды: он будет соответствовать каждому символу.

Мы можем изменить значение переменной HISTIGNORE следующим образом:

$ HISTIGNORE="ls *:history"
$ echo "this command will be included in history"
this command will be included in history
$ ls -l
-rw-rw-r--. 1 egdoc egdoc    0 Jan  7 11:51 file.txt
$ history
    1 HISTIGNORE="ls *:history"
    2 echo "This command will be included in the shell history"

Переменная HISTSIZE

Переменная HISTSIZE управляет количеством команд, хранящихся в истории Bash.

По умолчанию установлено значение 1000:

$ echo $HISTSIZE
1000

Мы можем увеличить или уменьшить это значение и настроить его в соответствии с нашими потребностями.

Если мы превысим указанное значение, старые команды будут удалены из начала списка:

HISTSIZE=3
$ echo "first command"
first command
$ echo "second command"
second command
$ echo "third command"
third command
$ history
    2 echo "first command"
    3 echo "second command"
    4 echo "third command"

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

Сохраняются только три команды.

Переменная HISTTIMEFORMAT

Переменная HISTTIMEFORMAT может быть использована для префиксации каждой команды в истории командного интерпретатора временной меткой.

Формат временной метки определяется значением, присвоенным переменной HISTTIMEFORMAT.

Можно использовать следующие обозначения:

Условные обозначения Значение
%d День
%m Месяц
%Y Год
%H Часы
%M Минуты
%S Секунды

Как всегда, давайте рассмотрим пример.

Допустим, мы хотим, чтобы каждая команда в истории была снабжена префиксом даты, в которую она была запущена, используя формат YYYY/MM/DD.

Вот значение, которое мы присвоим переменной:

$ HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "
$ echo "this command will be prefixed by a timestamp in shell history"
This command will be prefixed by a timestamp in shell history
$ history
    1  2022/01/07 17:12:09 HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "
    2  2022/01/07 17:12:12 echo "this command will be prefixed by a timestamp in shell history

Заключение

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

Мы рассмотрели, что история изначально хранится в памяти, а затем сохраняется в так называемом “history file”, когда сеанс оболочки закрыт.

Мы видели, как визуализировать текущую историю оболочки, как очистить ее и как заставить ее немедленно записываться в файл с помощью команды “history”.

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

🐧 Как очистить историю bash при выходе из системы

 

Добавить комментарий