“history -w”和关闭shell会话的操作有什么区别?

“history -w”和关闭shell会话的操作有什么区别?

我做了一些关于历史的测试:

  1. 我运行history-c然后退出。这清除了当前 shell 的历史记录。

  2. 我运行了history -c && history -w。这删除了所有内容。

  3. 我用 vi 编辑器删除了历史文件的全部内容:$vi ~/.bash_history。然后我注销了。下次登录时,运行时history只剩下最后一个 shell 会话的行或命令。

history -w这表明,和我们关闭 shell 会话时的操作是有区别的。

当我们关闭 shell 会话时到底发生了什么?

我认为history -w将内存内容覆盖到历史文件,并history -c删除内存内容。这是正确的吗?

答案1

处理 Bash 历史记录时,我们有两种:

  1. 内存中的历史列表
  2. .bash_history磁盘上的文件

当 Bash 启动时(假设采用默认配置),它会将文件内容加载.bash_history到内存中的历史列表中(如果需要,则将其截断为配置的大小)。

然后你输入的命令只会被添加到内存中的历史列表中。磁盘上的历史文件不会被触及。

定期退出 Bash 会话(不是强行终止它或导致它以某种方式崩溃)默认会截断内存中的历史记录列表以适应配置的最大大小,然后仅将当前 Bash 会话中的新条目附加(因为默认情况下该histappend选项是启用的)到磁盘上的历史记录文件,而不会删除已移除的条目或重新添加以前会话的内容。


当您运行时,history -c您会清除内存中的完整历史记录列表,但这不会影响磁盘上的历史文件。

运行history -w会将内存中的当前历史记录列表写入磁盘上的历史文件。它不会添加新条目,但会覆盖整个文件。因此,运行history -c && history -w实际上也会清除历史文件。


通过在正在运行的 Bash 会话中编辑历史文件来手动清除历史文件并没有达到预期的效果,也没有永久删除整个历史记录,因为内存中仍然包含历史文件中的所有旧条目的历史列表将保持不变。

退出 Bash 会话时,历史记录文件将使用历史记录列表中的数据进行重写。但是,由于默认情况下histappend启用了此选项,因此只有当前 Bash 会话中的新条目才会写入文件,较旧的历史数据将被丢弃。您必须运行history -w才能将完整的历史记录列表保存到磁盘。


当 Bash shell 启动和退出时具体发生什么可以读到man bash

HISTORY
       When the -o history option to the set builtin  is  enabled,  the  shell
       provides access to the command history, the list of commands previously
       typed.  The value of the HISTSIZE variable is used  as  the  number  of
       commands to save in a history list.  The text of the last HISTSIZE com‐
       mands (default 500) is saved.  The shell stores  each  command  in  the
       history  list  prior to parameter and variable expansion (see EXPANSION
       above) but after history expansion is performed, subject to the  values
       of the shell variables HISTIGNORE and HISTCONTROL.

       On startup, the history is initialized from the file named by the vari‐
       able HISTFILE (default ~/.bash_history).  The file named by  the  value
       of  HISTFILE  is  truncated,  if necessary, to contain no more than the
       number of lines specified by the value of HISTFILESIZE.   If  HISTFILE‐
       SIZE  is unset, or set to null, a non-numeric value, or a numeric value
       less than zero, the history file is not truncated.   When  the  history
       file  is  read, lines beginning with the history comment character fol‐
       lowed immediately by a digit are interpreted as timestamps for the pre‐
       ceding history line.  These timestamps are optionally displayed depend‐
       ing on the value of the HISTTIMEFORMAT variable.   When  a  shell  with
       history  enabled  exits,  the  last $HISTSIZE lines are copied from the
       history list to $HISTFILE.  If the histappend shell option  is  enabled
       (see  the description of shopt under SHELL BUILTIN COMMANDS below), the
       lines are appended to the history file, otherwise the history  file  is
       overwritten.   If  HISTFILE  is  unset,  or  if  the  history  file  is
       unwritable, the history is not saved.  If the  HISTTIMEFORMAT  variable
       is  set,  time  stamps are written to the history file, marked with the
       history comment character, so they may be preserved across  shell  ses‐
       sions.   This  uses  the history comment character to distinguish time‐
       stamps from other history lines.  After saving the history, the history
       file is truncated to contain no more than HISTFILESIZE lines.  If HIST‐
       FILESIZE is unset, or set to null, a non-numeric value,  or  a  numeric
       value less than zero, the history file is not truncated.

相关内容