Каков наилучший способ автоматического удаления .zsh_history по истечении определенного времени?

Каков наилучший способ автоматического удаления .zsh_history по истечении определенного времени?

Я чувствую, что естьнет возможности настройки ZSHдля автоматического удаления .zsh_historyпо истечении определенного времени (например, старше одного месяца с текущего момента). Какой самый простой хак для этого?

решение1

Правильно, для . нет параметров истечения срока действия, основанных на времени .zsh_history. Вероятно, потому что любой тип истечения срока действия требует EXTENDED_HISTORYформата (который включает время начала для каждой команды), и EXTENDED_HISTORYэто новая(ая) функция — по крайней мере, более новая, чем большинство параметров истечения срока действия.

Кроме того, функциональность zsh не лучшим образом связана с нечетким понятием «время» — просто прочитайте ограничения на флаги подстановки времени, чтобы это понять:

Любая дробная часть разницы между временем доступа и текущей частью в соответствующих единицах игнорируется при сравнении. Например, echo *(ah-5)будет выведены файлы, доступ к которым осуществлялся в течение последних пяти часов, в то время как echo *(ah+5)будет выведены файлы, доступ к которым осуществлялся не менее шести часов назад, поскольку время строго между пятью и шестью часами рассматривается как пять часов.

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

Если вы хотите это сделать, как говорит LSerni, парсинг самостоятельно, вероятно, будет лучшим вариантом. Одна хитрость в этом заключается в том, что многострочные записи в истории записываются дословно, то есть на нескольких строках — поэтому вы не можете парсить их просто «построчно», потому что некоторые строки не являются записями истории, а являются продолжениями.

Меня также беспокоит то, что, вероятно, нетдействительнобезопасный способ сделать это, за исключением интеграции его с управлением историей zsh напрямую, поскольку любой внешний код, изменяющий файл истории, находится под постоянной опасностью вмешательства (или вмешательства) со стороны работающего экземпляра zsh. Я имею в виду, если только вы не написали что-то, что bashзапускается только тогда, когда выне может бытьбыть в системе, например, во время однопользовательских этапов загрузки или завершения работы.

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

Записи старше CUTOFFудаляются (в примере я использовал 7 дней, но вы можете легко изменить 7на 30или 31на один месяц). Предполагается, что это выполняется $HOMEв качестве рабочего каталога.

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

#!/usr/bin/python3

import shutil
import time
from itertools import dropwhile

CUTOFF = time.time() - (86400 * 7)  # one week ago

hist = []
shutil.copy2(".zsh_history", ".zsh_history.bak")
with open(".zsh_history.bak", "rb") as f:
    for l in f.readlines():
        if l.startswith(b': '):
            # Start of a new history entry
            # Add a new tuple (time, history_line) to the list
            ts = int(l.split(b':')[1])
            hist.append((ts, l))
            continue
        # Continuation line, append it to the previous entry
        prev = hist.pop()
        hist.append((prev[0], b''.join([prev[1], l])))

with open(".zsh_history.new", "wb") as f:
    # Drop list entries while timestamp < CUTOFF,
    # Then write contents of each remaining entry to file
    for l in dropwhile(lambda x: x[0] < CUTOFF, hist):
        f.write(l[1])

Связанный контент