Я чувствую, что естьнет возможности настройки 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])