zsh 中的无限历史记录

pfn*_*sel 82 command-history zsh

zsh,我想拥有无限的历史。我设置HISTSIZE=,在bash. 现在我导入一个旧的历史

mv old_history .history
Run Code Online (Sandbox Code Playgroud)

这是相当大

wc -l .history
43562 .history
Run Code Online (Sandbox Code Playgroud)

如果我现在关闭并重新开始zsh,我会看到

wc -l .history
32234 .history
Run Code Online (Sandbox Code Playgroud)

我不能有无限的历史记录zsh吗?

aur*_*ien 99

您的机器存在极限和可能性。

HISTFILE="$HOME/.zsh_history"
HISTSIZE=10000000
SAVEHIST=10000000
setopt BANG_HIST                 # Treat the '!' character specially during expansion.
setopt EXTENDED_HISTORY          # Write the history file in the ":start:elapsed;command" format.
setopt INC_APPEND_HISTORY        # Write to the history file immediately, not when the shell exits.
setopt SHARE_HISTORY             # Share history between all sessions.
setopt HIST_EXPIRE_DUPS_FIRST    # Expire duplicate entries first when trimming history.
setopt HIST_IGNORE_DUPS          # Don't record an entry that was just recorded again.
setopt HIST_IGNORE_ALL_DUPS      # Delete old recorded entry if new entry is a duplicate.
setopt HIST_FIND_NO_DUPS         # Do not display a line previously found.
setopt HIST_IGNORE_SPACE         # Don't record an entry starting with a space.
setopt HIST_SAVE_NO_DUPS         # Don't write duplicate entries in the history file.
setopt HIST_REDUCE_BLANKS        # Remove superfluous blanks before recording entry.
setopt HIST_VERIFY               # Don't execute immediately upon history expansion.
setopt HIST_BEEP                 # Beep when accessing nonexistent history.
Run Code Online (Sandbox Code Playgroud)

ZSH 邮件列表

您应该确定您拥有多少内存,允许历史记录占用多少内存(AFAIK 它始终完全加载到内存中)并采取相应措施。取消限制并不明智,因为它让您认为没有限制,而它始终受可用资源的限制。

或者,如果您认为您永远不会遇到资源耗尽的问题,您可以从limits.h 中将HISTSIZE 设置为LONG_MAX:这是HISTSIZE 可以拥有的最大数量。

其中解释了Gentoo解决方案:

export HISTSIZE=2000
export HISTFILE="$HOME/.history"
Run Code Online (Sandbox Code Playgroud)

如果没有以下命令,历史将不会被保存:

export SAVEHIST=$HISTSIZE
Run Code Online (Sandbox Code Playgroud)

为了防止历史记录重复的条目(例如 ls -l 在单个 shell 会话期间多次输入),您可以设置 hist_ignore_all_dups 选项:

setopt hist_ignore_all_dups
Run Code Online (Sandbox Code Playgroud)

防止特定条目被记录到历史记录中的一个有用技巧,在它们之前至少有一个空格。

setopt hist_ignore_space
Run Code Online (Sandbox Code Playgroud)

  • 您的问题是_我不能在 zsh 中拥有无限的历史记录吗?_ ZSH 作者回复 _No_ 但您可以根据需要进行设置。Gentoo 正确地解释了怎么做。 (4认同)
  • 这些解决方案都不适用于 zsh。大约一两周后它仍然会切断它。我多年来一直在处理这个问题,这太荒谬了。我最终使用 logrotate 来做到这一点。 (4认同)
  • 用户 $export HISTSIZE=9999999999999999999999999999999999999999999999999999999999999999999999999 您必须设置该数字以尽可能符合您的愿望和计算机的可能性。 (3认同)
  • 我不明白这如何回答我的问题。我的历史文件的大小是 683 kB,对我的记忆来说肯定不会太大吗? (2认同)
  • 不确定这是否有帮助,因为它不是您真正要问的,但是在 zsh 中,您需要在 history 命令后添加“1”以显示完整历史记录,否则您将获得最后 15 个条目。 (2认同)

Gil*_*il' 34

您需要同时设置HISTSIZESAVEHIST。它们分别指示要在内存中保留多少行历史记录以及要在历史记录文件中保留多少行。

我不认为 zsh 有一个意味着“无限”的设置,但出于所有实际目的,十亿是无限的,同时在 32 位机器上保持机器可表示性。

HISTFILE=~/.zsh_history
HISTSIZE=999999999
SAVEHIST=$HISTSIZE
Run Code Online (Sandbox Code Playgroud)

  • 您一生中不会输入足够多的历史记录来降低 2010 年代 PC 的速度。 (19认同)
  • @talz因为默认的zsh配置已经有三十多年的历史了(zsh似乎更倾向于向后兼容而不是对新用户的友好)。即使在今天,仍然存在(越来越罕见)大尺寸可能成为问题的情况,例如,如果您的主目录位于网络文件系统上,或者如果您在小型嵌入式设备上选择 zsh(例如,wrt 路由器,而不是树莓派)。 (3认同)

Mat*_*eld 6

我有在经过了封的历史问题10000,直到我意识到,哦,我的-的zsh被设置自己的HISTSIZESAVEHIST值。TL;DR,请确保将线条放在.zshrc.

我遇到的另一个问题是我的历史记录被截断为 1024 行。虽然我不确定为什么,但我通过以下方式解决了它:

  • 设置HISTFILE=$HOME/.zsh_hist(与以前不同的东西)
  • HISTFILE=$HOME/.bash_history明确设置~/.bashrc
  • 做正常的设置,比如HISTSIZE=100000SAVEHIST=100000

我认为这可能与我使用export设置有关,HISTFILE这导致 bash 在HISTFILE从 ZSH 交互式启动时使用相同的变量,这会截断它。设置 bash 历史文件可能没有必要,只要您确保不要export HISTFILE.

  • 谢谢!我在 zprezto 上遇到了同样的问题。“为什么我的历史记录消失得这么快?我的 HISTSIZE/SAVEHIST 为 200 万,但 `wc -l .zhistory` 只有大约 10,000。” 奇怪的是,在运行时 shell 中,我看到了我的 .zshrc 值,但 zprezto 的历史模块确实将 SAVEHIST 初始化为 10,000,这一定有点粘。 (2认同)

pfn*_*sel 5

问题不在于zsh或 my .zshrc,而在于我的历史。有一些奇怪的条目,比如

^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@#1453692179
Run Code Online (Sandbox Code Playgroud)

令人困惑zsh,这些条目之后的所有内容都被截断了。我不知道^@对应的字符是什么,也不知道这些条目是如何出现在我的历史记录中的,但是删除它们可以解决问题。

  • ^@^@^@^@ 字符是空值,当两个程序尝试同时写入同一个文件时,它们经常出现,并且不使用原子写入(例如,它们是缓冲写入)或锁定. 或者它可能是由文件系统损坏、备份还原错误或类似原因引起的。 (10认同)
  • 这是一个有趣的线索,表明命令中的某种值可能会导致历史记录被截断。我想我已经发生过几次这种情况了。这是相当罕见的。我确实通过 cronjob 定期在 git 中跟踪我的历史文件,这样我就可以取回它。但仍然是一个巨大的麻烦。像这样的事件就是我一开始就设置这个的原因。这根本不是一个偏执的措施(尽管我的努力“也许”应该转向完整的系统备份设置)。我想知道我们是否可以使用 zsh 修复该错误。 (3认同)
  • `^@` 是 ASCII NUL (`\0`) 字符。 (2认同)
  • +1 用户222658;这些是 NUL,如果文件系统(或磁盘!)在写入附加数据之前写入更新的 inode 大小,则很容易由非原子“附加”文件系统操作和断电引起。(一些磁盘执行自己的写缓存,这些缓存重新排序写,这破坏了一些文件系统的内部一致性。) (2认同)