我感觉好像有没有 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
1 个月。)假设这是$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])