Игнорировать историю при использовании zsh

Вопрос или проблема

Я установил переменную HISTORY_IGNORE в ~/.zshrc, и она правильно предотвращает запись этих команд в ~/.zsh_history.

Но на самом деле я хочу, чтобы эти записи не отображались при нажатии вверх и вниз. (То же самое, что и HISTIGNORE при использовании bash).

Как мне этого добиться?

Вам нужно написать хуки для этого. Как указано в документации HISTORY_IGNORE:

Сравните опцию HIST_NO_STORE или хук zshaddhistory, каждый из которых предотвратит добавление таких команд в интерактивную историю вовсе. Если вы хотите использовать HISTORY_IGNORE, чтобы остановить добавление истории в первую очередь, вы можете определить следующий хук:

zshaddhistory() {
  emulate -L zsh
  ## раскомментируйте, если HISTORY_IGNORE
  ## должен использовать синтаксис EXTENDED_GLOB
  # setopt extendedglob
  [[ $1 != ${~HISTORY_IGNORE} ]]
}

Важно отметить из моего собственного тестирования:

  • $1 включает в себя разрыв строки в конце. Учитывайте это при написании вашего шаблона для HISTORY_IGNORE. Если это не учитывается, совпадение не произойдет.
  • Эта функция применяется всякий раз, когда Zsh записывает вашу историю из своей памяти в ваш файл истории. Таким образом, она ретроактивно удаляет строки из вашей истории. Будьте осторожны с этим!

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

zshaddhistory() {
  emulate -L zsh
  ## раскомментируйте, если HISTORY_IGNORE
  ## должен использовать синтаксис EXTENDED_GLOB
  # setopt extendedglob
  [[ $1 != ${~HISTORY_IGNORE}[[:space:]] ]]
}

Вы можете сопоставить и проигнорировать несколько пробельных символов в конце строки, включив расширенное совпадение и изменив строку совпадения на
[[ $1 != ${~HISTORY_IGNORE}[[:space:]]## ]]

Чтобы добавить контекст к предыдущему ответу:

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

zshaddhistory() {
    # Используйте стандартные настройки внутри этой функции.
    emulate -L zsh
    setopt extendedglob
    # Доказать, что $1 содержит новую строку
    printf "\$1 = '$1'\n"
    printf "\${HISTORY_IGNORE}='${HISTORY_IGNORE}'\n"
    # Проверьте статус вывода
    [[ $1 != ${~HISTORY_IGNORE} ]]
    echo $?
    # Вернуть фактический статус кода из функции, а не вывод.
    [[ $1 != ${~HISTORY_IGNORE} ]]
}

Ответ или решение

Как игнорировать команды в истории Zsh

Если вы используете Zsh и хотите игнорировать не только команды, которые не должны записываться в файл истории (~/.zsh_history), но и команды, которые не должны отображаться при нажатии клавиш вверх и вниз, вам потребуется написать функцию-хук. Стандартный параметр HISTORY_IGNORE предотвращает запись конкретных команд в файл истории, но не исключает их отображение в интерактивной истории.

Что такое HISTORY_IGNORE и как он работает

Переменная HISTORY_IGNORE используется в Zsh для того, чтобы задать шаблоны команд, которые не будут записываться в файл истории. Например, если вы хотите игнорировать команды вида ls, вы можете указать это в файле конфигурации ~/.zshrc:

HISTORY_IGNORE="ls"

Тем не менее, эта настройка не влияет на отображение команд при прокрутке истории с помощью клавиш вверх и вниз. Чтобы команд не было видно в интерактивной истории, потребуется использовать дополнительный функционал Zsh, а именно — хук zshaddhistory.

Определение хука zshaddhistory

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

Вот пример, как это можно сделать:

zshaddhistory() {
  emulate -L zsh
  setopt extendedglob
  [[ $1 != ${~HISTORY_IGNORE}[[:space:]] ]]
}

Этот хук работает следующим образом:

  1. Использование emulate -L zsh: гарантирует, что команды внутри функции используют стандартные настройки оболочки.
  2. Параметр setopt extendedglob: позволяет использовать расширенные шаблоны для сопоставления.
  3. Проверка с помощью [[ $1 != ${~HISTORY_IGNORE}[[:space:]] ]]: основная логика функции, исключающая команды, которые совпадают с шаблоном HISTORY_IGNORE, включая пробелы в конце строки.

Обработка пробелов и отладка

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

zshaddhistory() {
    emulate -L zsh
    setopt extendedglob
    printf "\$1 = '$1'\n"
    printf "\${HISTORY_IGNORE}='${HISTORY_IGNORE}'\n"
    echo $?
    [[ $1 != ${~HISTORY_IGNORE} ]]
}

Важные моменты при использовании

  1. Ретроактивное изменение истории: Учтите, что функция zshaddhistory вызывается каждый раз, когда Zsh записывает историю из своей памяти в файл, что может привести к исключению команд, которые вы уже выполнили.
  2. Исключение маски: Если ваша команда должна совпадать с несколькими шаблонами, убедитесь, что вы указали их в переменной HISTORY_IGNORE.
  3. Обратите внимание на настройки: Убедитесь, что вы корректно сохраняете ваш файл ~/.zshrc и перезапускаете терминал, чтобы изменения вступили в силу.

Заключение

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

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

Капча загружается...