153

If I run history, I can see my latest executed commands.

But if I do tail -f $HISTFILE or tail -f ~/.bash_history, they do not get listed.

Does the file get locked, is there a temporary location or something similar?

6 Answers 6

182

Bash maintains the list of commands internally in memory while it's running. They are written into .bash_history on exit:

When an interactive shell exits, the last $HISTSIZE lines are copied from the history list to the file named by $HISTFILE

If you want to force the command history to be written out, you can use the history -a command, which will:

Append the new history lines (history lines entered since the beginning of the current Bash session) to the history file.

There is also a -w option:

Write out the current history to the history file.

which may suit you more depending on exactly how you use your history.

If you want to make sure that they're always written immediately, you can put that command into your PROMPT_COMMAND variable:

export PROMPT_COMMAND='history -a'
4
  • 2
    Side note: if your .bash_history file accidentally becomes owned by root, things stop working. In that case, check the ownership and use sudo to fix the ownership if needed.
    – torek
    Jul 4, 2019 at 3:53
  • man history doesn't list a -a or -w option. What am I missing? Sep 29, 2021 at 21:57
  • 1
    @young_souvlaki I expect your man history is for a library; at least, that's what the only such man page I have available says at the top. It would be unusual for a library to document command-line options of other software, but help history (in Bash) will show applicable Bash documentation. Sep 30, 2021 at 0:33
  • Thank you! You are correct! Oddly man history defaults to "history(n)" under "Tcl Built-In Commands". man 3 history gives the "Library Functions Manual". help history gives the options described. Oct 1, 2021 at 15:17
25

(Not an answer but I cannot add comments)

If you are checking .bash_history because you just want delete a specific command (e.g. containing a password in clear), you can directly delete the entry in memory by history -d <entry_id>.

For example, supposing an output like:

$ history
926  ll
927  cd ..
928  export --password=super_secret
929  ll

and you want purge the export line, you can simply achieve it by:

history -d 928
13

bash keeps it in working memory, bash can be configured to save it when bash closes or after each command, and to be loaded when bash starts or on request.

If you configure to save after each command, then consider the implications of having multiple bash running at same time. (command lines will be interleaved)

2
  • 3
    The start of you answer makes it sound as if the history is stored in a file called bash, or even in the bash exetable. I would write "It is stored by bash in memory, ..."
    – Anthon
    Jul 18, 2014 at 9:08
  • that's indeed better
    – Anthon
    Jul 18, 2014 at 13:24
8

While running, the history is kept only in memory (by default) if:

  • set -o history (an H in echo "$-") is set.
  • HISTSIZE is not 0 and
  • HISTIGNORE is not * (or some other very restrictive pattern).

If any of the above fail, no history is stored in memory and consequently no history could or will be written to disk.

History in memory is written to disk if:

  • HISTFILESIZE is not 0 and
  • HISTFILE is not unset.

But only when the shell exits or if the commands history -a (append) or history -w (write) are executed.

To trigger an immediate write to disk you can use the variable:

 PROMPT_COMMAND='history -a'

which will append the new history lines to the history file. These are history lines entered since the beginning of the current bash session, but not already appended to the history file.

Or:

 PROMPT_COMMAND='history -w'

To overwrite the history in the HISTFILE with the list from memory.

So, you can remove a command from the history in memory:

 $ history 5
  6359  ls
  6360  cd ..
  6361  comand --private-password='^%^&$@#)!@*'
  6362  top
  6363  set +o | less
 $ history -d 6361
 $ history 5
  6359  ls
  6360  cd ..
  6361  top
  6362  set +o | less
 $ history -w

And write it to disk with the last command:

 history -w    # with `shopt -u histappend` unset
3
  • Would there be anything wrong by putting this in a cron job ? I suspect that a lot of users with far fewer usernames are logging on to a particular server and still history is fairly small and this is an old server, but maybe some session are never being closed... Oct 2, 2019 at 11:26
  • 1
    @oneindelijk history only writes the current shell's in-memory history to the history file. A cron job would presumably not have access to the history of other running shells.
    – wensveen
    Mar 27, 2020 at 14:22
  • how can we prevent multiple terminals command history from clobbering each other?
    – daparic
    Sep 5, 2020 at 8:19
6

Commands are saved in memory (RAM) while your session is active. As soon as you close the shell, the commands list gets written to .bash_history before shutdown.

Thus, you won't see history of current session in .bash_history.

2
  • 4
    The history file is updated upon bash termination, which does not imply rebooting (especially in graphical environments where you can open and close terminals as you wish). Jul 18, 2014 at 12:50
  • He probably meant "shutdown" the shell.
    – bomben
    Apr 8, 2021 at 11:00
2

The easiest way to find where your bash history is stored is with this:

echo $HISTFILE

You must log in to answer this question.

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