Bash history handling with multiple terminals

109,942

Solution 1

The bash session that is saved is the one for the terminal that is closed the latest. If you want to save the commands for every session, you could use the trick explained here.

export PROMPT_COMMAND='history -a'

To quote the manpage: “If set, the value is executed as a command prior to issuing each primary prompt.”

So every time my command has finished, it appends the unwritten history item to ~/.bash_history before displaying the prompt (only $PS1) again.

So after putting that line in /etc/bash.bashrc I don’t have to find myself reinventing wheels or lose valuable seconds re-typing stuff just because I was lazy with my terminals.

Anyway, you'll need to take into account that commands from different sessions will be mixed in your history file so it won't be so straightforward to read it later.

See also:

Solution 2

After multiple readings of man bash, I use separate history files for each shell. I did a mkdir -m 0700 ~/.history then added

[[ -d ~/.history ]] || mkdir --mode=0700 ~/.history
[[ -d ~/.history ]] && chmod 0700 ~/.history
HISTFILE=~/.history/history.$(date +%y%b%d-%H%M%S).$$
# close any old history file by zeroing HISTFILESIZE  
HISTFILESIZE=0  
# then set HISTFILESIZE to a large value
HISTFILESIZE=4096  
HISTSIZE=4096  

to my ~/.bashrc. Every now and then, I remember to du -sk .history and clean it out. It's nice to have every command I've typed preserved for me.

I just used the above to see what I'd been doing, of late:
cut -f1 "-d " .history/* | sort | uniq -c |sort -n -r |less
or
cut -f1-2 "-d " .history/* | sort | uniq -c |sort -n -r |less
(to include the 1st argument e.g. sudo mount in the sort chain).

Solution 3

See also "keeping persistent history in bash" for another alternative. It rigs your prompt to send all commands ever typed into any terminal into a "persistent history" file (alongside what's usually done for the regular .history).

Solution 4

To show history from all terminals:

Add export PROMPT_COMMAND='history -a; history -r' to your .bashrc file.

Source: http://northernmost.org/blog/flush-bash_history-after-each-command


Solution 5

History from all shell sessions is less useful than I hoped!

I enthusiastically set PROMPT_COMMAND='history -a; history -r' in the hopes that my history usage would be much better!

Wow, was I disappointed.

Essentially, doing this makes up/dn arrow useless. Because now each history session is littered with commands from other sessions. And for me this loses the best feature of history.

What I really wanted

Occasionally, I wanted to essentially transfer my history from one terminal session to another session so I could easily recall commands from that session. And I can do this very selectively.

What I did

I set up a series of simple history manipulation aliases & I ignore these commands in the history:

alias ha="history -a"
alias hb="history -a; history -r"
alias hr="history -r"
alias hl="history | tail -20"
HISTIGNORE="ha:hb:hr:hl"

I think of hb as history blend...the others are self-explanatory.

Now when I want to copy my history from session A to session B, I can do this:

  • A: ha - append session A history to history file
  • B: hb - append session B history to history file and then read the file

This essentially preserves the history order for session B and adds session A history deeper in the list.

Super useful for me. Maybe helps you too!

Share:
109,942

Related videos on Youtube

zetah
Author by

zetah

Updated on September 18, 2022

Comments

  • zetah
    zetah over 1 year

    I use mainly Terminator, and it's usually opened with 3 split terminal windows. I also use Gnome terminal for various reasons.
    I'm wondering how is bash history handled in this case as I sometimes miss previously issued commands when I run history

    For example, my prompt shows current bash history line (\!) and if I launch Terminator with 3 split terminal windows I get same history line (let's say 100) on all terminals. Which history will be saved?

    Also launching Gnome Terminal after using Terminator I get line 100 at startup regardless all commands issued before in Terminator

  • Vineet Menon
    Vineet Menon over 12 years
    isn't it stored separately for different TTL??
  • zetah
    zetah over 12 years
    Excellent. Thanks for explanation and solution. I tried with export PROMPT_COMMAND='history -a; history -r' and I got some strange history line numbers in terminal - after issuing some command history line number jumps by 2000 instead by 1, which is strange but it behaves as said - all terminals history is saved.
  • user2342005
    user2342005 over 11 years
    Why do you assign HISTFILESIZE twice?
  • goo
    goo over 11 years
    By setting HISTFILESIZE to 0, I clear the history buffer and reset the history saving mechanism. Then, I set the size I really want, and start saving history in HISTFILE. See the HISTORY section of man bash.
  • n611x007
    n611x007 about 11 years
    is there a way to merge the history files in order to make Ctrl+r work again?
  • goo
    goo about 11 years
    This should be a new question, but I don't think it's a Good Idea. I use egrep 'whatever' .history/* (or cat .history/* | egrep 'whatever') instead, and use Ctrl-r to search an individual session's history. Read man bash-builtins about the history command. My sort .history/* | uniq -c | sort -n | wc -l shows 16033 unique commands, cut '-d ' -f1 .history/* | sort | uniq -c | sort -n shows 2004 unique commands, mostly typos. Loading all that into bash's "history list" would not help.
  • Elijah Lynn
    Elijah Lynn about 10 years
    I will say that after a couple months of using this I eventually commented this out just recently. It is bittersweet as I don't always want to sift through the last 100 commands just to run the one I had originally run in the Tmux pane I sometimes may have a dedicated log command in that I need to restart.
  • Shubham
    Shubham over 6 years
  • Evgeni Sergeev
    Evgeni Sergeev about 6 years
    I inserted $$ to make the line echo $$ $date_part "$command_part" >> ~/.persistent_history This prefixes the entries with the PIDs of their bash process, so that we can disentangle multiple histories.
  • Elijah Lynn
    Elijah Lynn almost 6 years
    A nice solution that the fish shell offers is a history --merge. I have been using this for a year or so now and it solves the issue. When I want the most recent history from other sessions, I just run that command and it is available to me instantly.
  • max
    max over 5 years
    Can the alternative history be made to work with CTRL-R history search?
  • unsynchronized
    unsynchronized about 5 years
    @waltinator - i know this is an old comment, but are you implying that setting an environment variable somehow triggers an immediate action? what process is going to pick up the fact you assigned a value of 0 to HISTFILESIZE in a local shell and then immediately change to 4096? is this something undocumented about bash's handling of certain variable names?
  • Marc.2377
    Marc.2377 almost 5 years
  • lmat - Reinstate Monica
    lmat - Reinstate Monica almost 5 years
    "won't be so straightforward to read it later." How do you work? I usually work on one terminal at a time following a thread of thought ;-) The history shouldn't be much worse than your train of thought...
  • lmat - Reinstate Monica
    lmat - Reinstate Monica almost 5 years
    @Daniel To invoke the Deep Magic.
  • lmat - Reinstate Monica
    lmat - Reinstate Monica almost 5 years
    export is not needed.
  • goo
    goo over 4 years
    @unsynchronized: See man bash, the part that starts withThe following variables are used by the shell.
  • n1k31t4
    n1k31t4 over 4 years
    (+1) Is it actually necessary to first run mkdir -m 0700 ~/.history, then also include it in the second condition in your first line of the code block: [[ -d ~/.history ]] || mkdir --mode=0700 ~/.history ? Do the first two lines not ensure (with each new terminal when .bashrc is executed) that the folder exists with the expected permissions?
  • goo
    goo over 4 years
    @n1k31t4 No, not actually necessary, but included for documentation. It's easier to simply set the permission to "what's Right", than to check with stat -c "%a" ~/.history/ and then fix it if it's wrong. Yes, the two lines ensure that, every time through ~/.bashrc, my ~/.history directory exists with the Right permissions.
  • fooBar
    fooBar over 2 years
    Use ctrl+R to search your history from terminal, that will help with mixed shells...