6

I'm trying to figure out how to fork/clone a terminal that retains the history of its parent.

I understand there are solutions that allow all terminals to share a history, but this is not quite what I'm after.

Sometimes I am working in a directory and realize I need an additional terminal - but still want easy access to the command history in that terminal without switching back and forth to its parent.

Note: There is no need for the two terminals to continue updating each other's history once the child is spawned.

Example:

  • Super-long-weird-command-executed-in-terminal-1
  • Need an additional terminal - Terminal 2 has entered the game.
  • After some time, I end up launching nano in Terminal 1
  • Need that super long command from Terminal 1 - but luckily its in the history of Terminal 2!
Ramrod
  • 163
  • 1
    There is no need for the two terminals to continue updating each other's history once the child is spawned or do you explicitly want to avoid this? – kos Jan 07 '16 at 18:39
  • It's fine if they maintain a shared history, although it isn't a requirement. – Ramrod Jan 07 '16 at 18:42
  • 2
    history is a property of the shell - not the terminal: see How to save terminal history manually?, in particularly the usage of history -a in bash – steeldriver Jan 07 '16 at 18:45
  • Then how about steeldriver's linked question? It seems like it will allow you to accomplish what you're after. – kos Jan 07 '16 at 18:47
  • @kos - I suppose that would work, but as I read it then all terminal instances would update one large shell history (as alluded to by @steeldriver). Perhaps this entire question is a misunderstanding on my part of the intricacies of terminals vs shells. – Ramrod Jan 07 '16 at 18:50
  • No, you're correct. Then the only solution occurring to me right now would be creating an alias such as alias newterminal='history -a && gnome-terminal', so that running newterminal in the current shell would append the current history and spawn another terminal. But then you'd be obliged to spawn the new terminal by running the alias in the current shell. – kos Jan 07 '16 at 19:16

1 Answers1

5

In a nutshell:

To open a new terminal window with the same full history as the current session, run:

 history -a && gnome-terminal

Full explanation:

The Bash history works like this:

  • You open a terminal which starts a Bash session.
  • Bash loads the old history from $HISTFILE, which is usually ~/.bash_history.
  • You can enter commands into the Bash shell. Those commands will be stored in a temporary history in memory.
  • You exit the Bash session or close the terminal window.
  • Before Bash terminates, it synchronizes the temporary history in memory with the one saved in $HISTFILE on the disk.

Note that for both the temporary and the persistent history may have size limits and get truncated when they become too long.

As each Bash instance only writes to a temporary history in your memory, the actions from a running session do not appear if you start a second session in parallel: It will load the old version of the persistent history file!


If you need to synchronize the temporary histories of two Bash instances, you need to do this via the persistent history file. There is a command to help you: history

  • To flush the current Bash session's temporary history from RAM to the $HISTFILE on the disk by appending the new command lines to it, you run:

     history -a
    

    This command gets automatically invoked whenever you exit a Bash session.

  • To re-read the $HISTFILE from the disk and add the new command lines from it to the current Bash session's temporary history which you can use, you run:

     history -r
    

    This command gets automatically invoked whenever you start a Bash session.

Note the leading space in front of both history commands. It prevents that the history command itself will appear in the Bash history. If you want it to appear there, just omit the space at the beginning.


So to open a new terminal window that has access to all the current history, you need to flush the current temporary history first, and then open a new terminal with a new Bash session:

 history -a && gnome-terminal

Again, note the space in the beginning to prevent this command to appear in the histories. If you want it to appear there, omit the space in front of the command.

If you want a short command for that, create a Bash alias:

echo "alias newterminal='history -a && gnome-terminal'" >> .bash_aliases

You could also add a context menu entry to the Gnome-Terminal launcher if you want. Ask for it in a comment if you need it.


To synchronize the histories of two already open terminal windows, first flush the history of the first window, then reload the history file in the second window:

  • Terminal 1 (source):

     history -a
    
  • Terminal 2 (target):

     history -r
    

If you need a two-ways synchronisation, first run the history -a commands on all windows, then run the history -r everywhere.


More information about the history command can be found when you execute

help history
Byte Commander
  • 107,489