Where is bash’s history stored?
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
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.
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'
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.
@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.
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.
(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 .
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:
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)
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, . «
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:
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:
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.
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
How can I see all of the bash history?
In this case, the shell can not see the history executed by shell(1), but I want to see all of the bash history in every shell. So my question is how can I see all of the bash history? Does anybody know how to hack? Thank you very much in advance!
5 Answers 5
would also work, although I tend to just use
How to do it when I am working in a virtual environment (venv)? ~/.bash_history shows only the commands outside of the virtual environment.
@Raif — you would need access to the terminal within the virtual environment as the «user» running the app commands (root or the equivalent).
You should look into the histappend shell option and the -a flag to history :
histappend
If set, the history list is appended to the file named by the value of the HISTFILE variable when the shell exits, rather than overwriting the file.
history
-a Append the «new» history lines (history lines entered since the beginning of the current bash session) to the history file.
If you put history -a into your PROMPT_COMMAND , you’ll get an always-up-to-date .bash_history file.
Edit your .bashrc and append this to it’s end:
shopt -s histappend PROMPT_COMMAND="history -n; history -a" unset HISTFILESIZE HISTSIZE=2000
You can install something like Advanced Shell History, which will log each command to a sqlite3 database. It comes with a tool for querying the database from the command line. https://github.com/barabo/advanced-shell-history
With this setup, you will have a unified view of command history across all sessions. You also get things like command history for the current working directory (or subtree), command exit code, command duration, etc.
Full disclosure: I wrote and maintain the tool.
As several have noted, you need to use shopt -s histappend . Check by running shopt and verifying that histappend is ‘on’.
To ensure that each command (across multiple concurrent shells) appears in the history for each of those shells, add this at the end of your .bashrc file:
# Skip if not an interactive shell if [ -z "$" ]; then return; fi export PROMPT_COMMAND="history -a; history -c; history -r; $"
-a: appends the new history lines (history lines entered since the beginning of the current Bash session) to the history file.
-c: clears the history list.
-r: reads the current history file and append its contents to the history list.
Run source .bashrc or create new sessions and in several terminal windows enter the comment #Tn in each. Then on one terminal, enter history | tail -N to see the last N lines. You should see all of the comments entered on the different terminals.
It may be helpful to add the following to /etc/profile.d/bashrc.sh in order to get a timestamp on each line of the history:
if [ -z "$" ]; then return; fi export HISTTIMEFORMAT='%F %T '
The result looks like this:
[moi@laBoheme ~]$ history | tail -4 3292 2019-01-22 12:41:25 # T1 3293 2019-01-22 12:41:32 # T2 3294 2019-01-22 12:41:44 # T3 3295 2019-01-22 12:41:50 history | tail -4
How to use the history command in Linux
As I spend more and more time in terminal sessions, it feels like I’m continually finding new commands that make my daily tasks more efficient. The GNU history command is one that really changed my work day.
The GNU history command keeps a list of all the other commands that have been run from that terminal session, then allows you to replay or reuse those commands instead of retyping them. If you are an experienced terminal user, you know about the power of history , but for us dabblers or new sysadmin folks, history is an immediate productivity gain.
First of all, the history command isn’t actually a command. You can see this for yourself by looking for the command on your system:
$ which history which: no history in (/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/local/sbin)
Your computer can’t find the history command because it’s a built-in keyword of your shell. Because it’s written into the shell you’re using, there can be some variation in how history behaves depending on whether you’re using Bash, tcsh, Zsh, dash, fish, ksh, and so on. This article is based upon the Bash implementation of history, so some functions may not work in other shells. However, most of the basic functions are the same.
History 101
To see history in action, open a terminal program on your Linux installation and type:
1 clear 2 ls -al 3 sudo dnf update -y 4 history
The history command shows a list of the commands entered since you started the session. The joy of history is that now you can replay any of them by using a command such as:
The !3 command at the prompt tells the shell to rerun the command on line 3 of the history list. I could also access that command by entering:
This prompts history to search for the last command that matches the pattern you provided (in this case, that pattern is dnf) and run it.
Searching history
You can also use history to rerun the last command you entered by typing !! . By pairing it with grep , you can search for commands that match a text pattern or, by using it with tail , you can find the last few commands you executed. For example:
$ history | grep dnf 3 sudo dnf update -y 5 history | grep dnf $ history | tail -n 3 4 history 5 history | grep dnf 6 history | tail -n 3
Another way to get to this search functionality is by typing Ctrl-R to invoke a recursive search of your command history. After typing this, the prompt changes to:
Now you can start typing a command, and matching commands will be displayed for you to execute by pressing Return or Enter.
Changing an executed command
You can also use history to rerun a command with different syntax. You can revise history with history . For example, if I want to change my previous command history | grep dnf to history | grep ssh , I can execute the following at the prompt:
The command is rerun, but with dnf replaced by ssh . In other words, this command is run:
Removing history
There may come a time that you want to remove some or all the commands in your history file. If you want to delete a particular command, enter history -d . To clear the entire contents of the history file, execute history -c .
The history file is stored in a file that you can modify, as well. Bash shell users find it in their home directory as .bash_history .
Next steps
There are a number of other things that you can do with history :
- Set the size of your history buffer to a certain number of commands
- Record the date and time for each line in history
- Prevent certain commands from being recorded in history
For more information about the history command and other interesting things you can do with it, take a look at Seth Kenlon’s articles about parsing history, history search modifiers, and the GNU Bash Manual.
This article was originally published in June 2018 and has been updated with additional information by the editor.