20

I used the answer in https://unix.stackexchange.com/a/1292/41729 to enable real-time shared history among separate Bash terminals. As explained in the answer above, this is achieved by adding the following to .bashrc:

# Avoid duplicates
HISTCONTROL=ignoredups:erasedups
# When the shell exits, append to the history file instead of overwriting it
shopt -s histappend

# After each command, save and reload history
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

This works fine if the Bash shells are separate (e.g. opening different Bash terminals using CTRL+ALT+T. However it doesn't work if I use tabs (from an open terminal CTRL+SHIFT+T) rather than new windows. Why this difference in behaviour? How can I share the Bash history also among various tabs?

UPDATE: I noticed an unusual behaviour: If I type CTRL+C then the last command typed in any of the other terminals (both a tab or not) is correctly displayed. It is like if the CTRL+C forces a flush of the history so that then it is correctly shared.

As an example, the outputs (T1 denotes terminal 1 and T2 terminal 2):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<up> (i.e. I press the up arrow)
ls -lah # i.e the last command in terminal 1 is shown rather than the last of terminal 2
^C (i.e. I press CTRL+C)
<up>
cd Documents # the last command issued in terminal 2 is correctly displayed
2
  • You added that to your ~.bashrc file? On a side note, exporting those variables is pointless; just wastes environment space.
    – geirha
    Jun 24, 2013 at 9:03
  • @geirha yes I have added to my .bashrc file. Thanks for the comment on the export.
    – lucacerone
    Jun 24, 2013 at 10:07

4 Answers 4

2

It looks like you're trying to access the other terminal's history before the sync takes place. PROMPT_COMMAND is executed right before a new prompt is printed, i.e., after you run a command and before you type the next command. So it won't happen right away in T1; you have to cause a new prompt to be displayed.

To test this, try this variant on your steps (I added an extra <enter> in T1):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<enter>
<up> (i.e. I press the up arrow)

With this extra press of enter, you get a new prompt, which runs PROMPT_COMMAND and syncs your history, and so I would expect this up arrow to retrieve the cd instead of the ls, as you wanted. Unfortunately, I don't think there is a way to make the sync happen instantaneously in all terminals without running any commands as you seem to want; effectively this would require all of your login sessions to be synchronizing their history lists continuously all the time, which would be a huge waste of CPU and disk throughput.

1
  • you are right, pressing enter it is synced after. Even if there is a waste of memory or CPU how could I force the sync ?(if it is too much I can always disable it, but I would like to give it a try)
    – lucacerone
    Jun 30, 2013 at 1:24
1

I asked the same question and here is the answer I came up with....

HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

history() {
  _bash_history_sync
  builtin history "$@"
}

_bash_history_sync() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
  builtin history -c         #3
  builtin history -r         #4
}

PROMPT_COMMAND=_bash_history_sync
4
  • Source: unix.stackexchange.com/a/48116/37944 Jun 26, 2013 at 10:59
  • two clarfications before I try: should I remove the other hystory - options then? this goes in .bashrc right?
    – lucacerone
    Jun 26, 2013 at 20:24
  • unfortunately it does not work...
    – lucacerone
    Jun 26, 2013 at 21:13
  • Each time HISTFILESIZE is changed it automatically attempts to truncate the existing history file. Changing HISTSIZE has a similar effect on the current history. For reference, see the comment in variables.c in the bash src just before sv_histsize. Jul 17, 2015 at 19:09
1

add that lines to your .bashrc file

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

trap 'history -r' USR1 
export PROMPT_COMMAND="history -a ; history -c; ps a | awk '/ bash$/ {system (\"kill -USR1 \" \$1)}'; $PROMPT_COMMAND"

note:

Initially I did my test bay sending USR1 signal to bash with killall, later I thought to use a uniquee shell name, a bash copy named testshell, to avoid killing my own shells that could run (cron processes for instance) but strangelly that was not working.

The killall was not selective enough, I replaced it with a script that kills only the bash processes tight to a tty (ps a reports only processes tied to a tty)

Do not forget to restart your session to have a fresh PROMPT_COMMAND, when I was testing I saw many of my previous test stacked inside PROMPT_COMMAND.

11
  • You don't need the new user and the other shell, you can just tell killall to send the signal only to processes of the same user with an additional -u argument, e.g. -u $(whoami)`. Jul 1, 2013 at 18:45
  • I think the syntax for csh is wrong... @PhilippWendler could you please elaborate a little bit?
    – lucacerone
    Jul 2, 2013 at 0:35
  • The question is about bash, so I used bash syntax. I don't know csh. For bash, killall -q -USR1 -u $(whoami) bash sends USR1 signal to all bash processes of the current user. Jul 2, 2013 at 5:00
  • @Philipp ty btw I didn't tested the dedicated shell solution, it was to fix a case where cron bash script would run.
    – Emmanuel
    Jul 2, 2013 at 7:01
  • @LucaCerone I rewrote seems to work
    – Emmanuel
    Jul 3, 2013 at 16:38
0

I had the same strange behavior in Yakuake when tried to create elaborate bash prompt which would show the number of another logins. Number didn't increase for tabs. My workaround was to tell Yakuake run bash again in every new tab, essentially starting bash in bash. It started to work flawlessly. May be it would help you too. My blind guess is that GUI for console loads bash configs itself and then feeds them to bash instances. May be it is to be able to fiddle with them.

1
  • I have tried to load bash in bash, but without any success :(
    – lucacerone
    Jun 26, 2013 at 21:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .