跨会话共享 shell 历史记录而不交错

Jan*_*hoł 4 shell bash command-history

这里有一个类似的问题,但我想实现不同的目标:我想在会话之间共享历史记录,但不将不同会话中执行的命令混合在一起。

例如,假设我有两个 shell 会话:A 和 B。我在 A 中键入一些命令:

A$ ls ~
A$ ls /etc
Run Code Online (Sandbox Code Playgroud)

在B中:

B$ git status
B$ git log
Run Code Online (Sandbox Code Playgroud)

当我在 shell 中键入时history,我希望在其他 shell 的命令之后一起查看此 shell 中的所有命令-这样就可以始终使用 uparrrow 从当前 shell 获取最后的命令。换句话说,在 shell A 中应该显示history

git status
git log
ls ~
ls /etc
Run Code Online (Sandbox Code Playgroud)

在 shell B 中它应该显示

ls ~
ls /etc
git status
git log
Run Code Online (Sandbox Code Playgroud)

这个怎么做?

Jan*_*hoł 6

似乎没有内置的解决方案,但事实证明手动实现它并不那么困难。人们必须单独存储每个会话的历史记录,并在每次提示时重新创建它(它并不像听起来那么慢)。核心逻辑如下:

# on every prompt, save new history to dedicated file and recreate full history
# by reading all files, always keeping history from current session on top.
update_history () {
  history -a ${HISTFILE}.$$
  history -c
  history -r
  for f in `ls ${HISTFILE}.[0-9]* | grep -v "${HISTFILE}.$$\$"`; do
    history -r $f
  done
  history -r "${HISTFILE}.$$"
}
export PROMPT_COMMAND='update_history'

# merge session history into main history file on bash exit
merge_session_history () {
  cat ${HISTFILE}.$$ >> $HISTFILE
  rm ${HISTFILE}.$$
}
trap merge_session_history EXIT
Run Code Online (Sandbox Code Playgroud)

请参阅此要点以获取完整的解决方案,包括一些保护措施和性能优化。