bash 保存历史记录但不退出

bash 保存历史记录但不退出

在 linux ubuntu bash 终端中。有没有办法保存 bash 历史记录而不写入 exit?我已将配置设置为“HISTCONTROL=erasedups”

在我看来,它比 ignoreups 效果更好。

无论如何,出于某种原因,除非我输入“退出”,否则它不会保存 bash 终端中的最后几个命令。我习惯于单击终端窗口上的十字,因此当我重新登录时,我总是对最后的命令没有保存感到恼火。

提醒: http://www.thegeekstuff.com/2008/08/15-examples-to-master-linux-command-line-history/#more-130

答案1

Bash 历史记录

.bash_history可以使用以下命令将在活动终端中发出的任何新命令附加到文件中:

history -a

唯一需要理解的棘手概念是每个终端都有自己的 bash 历史记录列表.bash_history(打开终端时从文件加载)

如果你想提取此活动终端生命周期内其他终端写入的任何新历史记录,你可以将以下内容附加到.bash_history 文件到活跃的 bash 历史记录列表

history -c;history -r

这将清除当前历史列表,以便我们不会得到重复的列表,并将历史文件附加到(现在为空的)列表中。

解决方案

您可以使用 bash 变量PROMPT_COMMAND在每个新提示符下发出一个命令(每次在终端中按下 Enter 键时)

export PROMPT_COMMAND='history -a'

这会将每个命令记录到历史记录中文件已发布。

结果

现在,您打开的任何新终端都将具有其他终端的历史记录,而无需访问exit其他终端。这是我喜欢的工作流程。

更精准

假设(由于某种原因)您有两个同时使用的终端,并且您希望历史记录反映在每个新命令之间。

export PROMPT_COMMAND='history -a;history -c;history -r'

这里的主要缺点是您可能需要按回车键重新运行 PROMPT_COMMAND 才能从对面的终端获取最新的历史记录。

您可以看到为什么这个更精确的选项可能有点过度,但它适用于该用例。

答案2

要将 bash 历史记录保存到文件:

history -w ~/history.txt
vim ~/history.txt

它会将历史记录导出到名为 history.txt 的文件中。然后您可以使用自己喜欢的编辑器查看它。

答案复制自http://tech.karbassi.com/2007/01/14/view-and-change-bash-history/

答案3

那里保存所有 bash 历史记录的方法到单独的文件,但如果您尝试使用历史记录机制,并且由于某种原因它没有保存您的所有历史记录,那就是另一个问题了。

无论终端发生什么,始终将所有历史记录保存到单独的文件中

此处提供的脚本成功了。

# don't put duplicate lines in the history. See bash(1) for more options
# ... and ignore same sucessive entries.
export HISTCONTROL=ignoreboth

# set the time format for the history file.
export HISTTIMEFORMAT="%Y.%m.%d %H:%M:%S "

# If this is an xterm set the title to user@host:dir
case "$TERM" in
  xterm*|rxvt*)
  # Show the currently running command in the terminal title:
  # http://www.davidpashley.com/articles/xterm-titles-with-bash.html
  show_command_in_title_bar()
  {
    case "$BASH_COMMAND" in
      *\033]0*)
      # The command is trying to set the title bar as well;
      # this is most likely the execution of $PROMPT_COMMAND.
      # In any case nested escapes confuse the terminal, so don't
      # output them.
      ;;
      *)
      if test ! "$BASH_COMMAND" = "log_bash_eternal_history"
      then
        echo -ne "\033]0;$(history 1 | sed 's/^ *[0-9]* *//') :: ${PWD} :: ${USER}@${HOSTNAME}\007"
      fi
      ;;
    esac
  }
  trap show_command_in_title_bar DEBUG
  ;;
  *)
  ;;
esac

log_bash_eternal_history()
{
  local rc=$?
  [[ $(history 1) =~ ^\ *[0-9]+\ +([^\ ]+\ [^\ ]+)\ +(.*)$ ]]
  local date_part="${BASH_REMATCH[1]}"
  local command_part="${BASH_REMATCH[2]}"
  if [ "$command_part" != "$ETERNAL_HISTORY_LAST" -a "$command_part" != "ls" -a "$command_part" != "ll" ]
  then
    echo $date_part $HOSTNAME $rc "$command_part" >> ~/.bash_eternal_history
    export ETERNAL_HISTORY_LAST="$command_part"
  fi
}

PROMPT_COMMAND="log_bash_eternal_history"

在虚拟终端窗口上单击 X 时告诉历史命令“立即保存!”

首先你要明白的是,bash当进程退出时,您的虚拟终端仿真器使用什么机制来终止它?-- 这取决于您所使用的具体终端仿真器。

有几种选择,所有这些都涉及UNIX 信号

  • SIGTERM、SIGINT、SIGQUIT:当 Bash 在交互模式下收到这些信号之一时,默认行为是忽略它,因此大概不是那个。

  • SIGHUP:此信号通常会导致 Bash 正常终止并进行清理,但我不确定该“清理”是否涉及保存历史文件。它可能不涉及。

  • SIGKILL、SIGSTOP:Bash 作为用户空间进程不可能忽略这些信号。内核可以随时使用这些信号强制终止或停止进程。如果您的 VT 仿真器发送了其中一个信号,我们无法捕获它并在退出之前执行某些操作,因此您很不幸。

一些参考: ServerFault 问题 337123

Unix 问题 6332

GNU Bash 手册中的“以交互方式使用历史记录”

答案4

我有tmux连续几天的会话,我想保存它们的历史记录,但是history -a当同时使用多个终端时,简单的操作会将不同的历史记录混杂在一起。

使用不同文件的另一种方法是定期保存它们,这样至少它们的历史记录在某种程度上是按连续的 N+ 分钟块组织的。下面的函数将每 15 分钟的使用时间附加到历史记录中,因此在频繁切换终端时,历史记录会更加一致。

# Append to bash history every few minutes - called from PROMPT_COMMAND
function append_history_periodically() {

    # update history every 15 minutes
    _BASH_UPDATE_PERIOD_SEC=$((15 * 60))

    if [ -z "${_BASH_HIST_LAST_UPDATE}" ]; then
        # time tracking not set - save current timestamp and return
        _BASH_HIST_LAST_UPDATE="$(date +%s)"
        return
    fi

    _BASH_NOW="$(date +%s)"
    _BASH_TIME_DIFF="$((_BASH_NOW - _BASH_HIST_LAST_UPDATE))"

    # append history and reset _BASH_HIST_LAST_UPDATE
    if [ "${_BASH_TIME_DIFF}" -gt "${_BASH_UPDATE_PERIOD_SEC}" ]; then
        history -a
        _BASH_HIST_LAST_UPDATE="${_BASH_NOW}"
    fi

    unset _BASH_TIME_DIFF
    unset _BASH_NOW

}
PROMPT_COMMAND='append_history_periodically'

相关内容