1

I've read the solutions at Preserve bash history in multiple terminal windows and I'm looking for the following compromise:

  1. Commands from all concurrent bash sessions are appended after being executed to one shared file
  2. Ctrl+r in one session finds commands from other sessions
  3. Pressing Up/Down in one session only cycles through the commands in that session.

Is this possible with bash? If not, with zsh maybe?

  • I do not think it is possible. I mean, at least in bash, you can share one history file, but each session manages it's own history in the memory. You can merge the history from the file to the session, but then it would also affect up/down keys. What I suggest is to replace ctrl+r with a different script/alias that would search through the file, maybe with grep. It wouldn't be the same, of course, but that's what I could come up with. – aviro Jan 04 '22 at 07:30

1 Answers1

2

I've stumbled upon this question while trying to achieve something similar. I believe the following solves your problem:

  1. Use a file to record all executed commands. Thanks to Eli Bendersky for his post, I use his code as it is, the only change is setting the filename in $PERSISTENT_HISTORY_FILE.

  2. Install fzf with key bindings (I'm unsure if installation via package manager sets key bindings, but via git and install script does).

  3. Change __fzf_history function in fzf/shell/key-bindings.bash to:

__fzf_history__() {
  local output opts script
  opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort ${FZF_CTRL_R_OPTS-} +m --read0"
  script='BEGIN { $/ = "\n"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++'
  output=$(
    tac $PERSISTENT_HISTORY_FILE |
        last_hist=$(HISTTIMEFORMAT='%F %T  ' builtin history 1) perl -n -l0 -e "$script" |
      FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) --query "$READLINE_LINE"
    ) || return
  READLINE_LINE=${output#*| }
  if [[ -z "$READLINE_POINT" ]]; then
    echo "$READLINE_LINE"
  else
    READLINE_POINT=0x7fffffff
  fi
}

Obviously, you can make your own function stripping the code above from fzf specifics and binding it to ctrl+r.

Skult
  • 21
  • I have a personal script, now I'm trying to figure out how to use this with that... I thought, maybe, adding your modified function to my script after sourcing key-bindings would do the trick, but when I tried it I got an error: unknown option: --scheme=history... – João Ciocca Apr 05 '23 at 21:51
  • 1
    Maybe it's something with your fzf version (too old/too buggy)? I've found this: https://github.com/junegunn/fzf/issues/2996 – Skult Apr 06 '23 at 22:27
  • I never paid attention that apt's version is so outdated! Switched to brew's install. It's working now, thank you very much! – João Ciocca Apr 07 '23 at 02:11