这是我的历史文件:
$ echo $HISTFILE
/home/Steven/.bash_history
我可以使用 exit 创建它:
$ [ -e $HISTFILE ]; echo $?
1
$ exit
$ [ -e $HISTFILE ]; echo $?
0
但是,如果我退出子 shell,则不会创建它:
$ [ -e $HISTFILE ]; echo $?
1
$ (exit)
$ [ -e $HISTFILE ]; echo $?
1
为什么没有在子 shell 中创建历史文件?
答案1
如果打开 bash shell,则会传递历史文件的内容。当它退出时,它将其历史记录附加到历史文件中。
如果您打开另一个(交互式)bash shell(在同一个终端窗口中),执行一些命令或仅执行命令exit
,这些命令(或仅执行命令exit
)将被附加到历史文件中。
但是,如果您运行非交互式子 shell,历史记录将关闭并且环境变量HISTFILE
将被取消设置。
您可以通过运行(bash -c 'echo x$HISTFILE')
或仅验证这一点bash -c 'echo x$HISTFILE'
。这只会 echo x
,证明该变量HISTFILE
在子 shell 中未设置。 (我只是添加了x
echo 命令的一些可见输出。)
( 的原因bash -c
和单引号它是为了防止父 shell 中的 shell 变量扩展。如果运行(echo x$HISTFILE)
,shell 变量扩展会将 的值传递HISTFILE
给子 shell,然后它会回显,使其看起来像是在子外壳)。
因此,当运行子 shell 时,历史记录将被关闭,并且变量HISTFILE
将被取消设置。当子 shell 退出时,历史记录中不会添加任何内容。这正是您所看到的。
您可以强制子 shell 将其历史记录写入历史文件:
$ history -w # write current history
$ wc -l $HISTFILE # count lines in history file
32 /home/anyuser/.bash_history
$ bash -c 'export HISTFILE=~/.bash_history'
$ wc -l $HISTFILE
32 /home/anyuser/.bash_history
$ bash -c 'export HISTFILE=~/.bash_history;history -w'
$ wc -l $HISTFILE
0 /home/anyuser/.bash_history
最后一个子 shell 命令(带有 的命令history -w
)会使用子 shell 的历史记录覆盖现有的历史记录文件,该文件为空,因为历史记录在非交互式子 shell 中被关闭。