Does file .bash_history always record every command I ever issue?
There are a number of environment variables that control how history works in Bash. Relevant excerpt from bash manpage follows:
HISTCONTROL
A colon-separated list of values controlling how commands are saved on the history list. If the list of values includes ignorespace, lines which
begin with a space character are not saved in the history list. A value of ignoredups causes lines matching the previous history entry to not be
saved. A value of ignoreboth is shorthand for ignorespace and ignoredups. A value of erasedups causes all previous lines matching the current
line to be removed from the history list before that line is saved. Any value not in the above list is ignored. If HISTCONTROL is unset, or does
not include a valid value, all lines read by the shell parser are saved on the history list, subject to the value of HISTIGNORE. The second and
subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of HISTCONTROL.
HISTFILE
The name of the file in which command history is saved (see HISTORY below). The default value is ~/.bash_history. If unset, the command history
is not saved when an interactive shell exits.
HISTFILESIZE
The maximum number of lines contained in the history file. When this variable is assigned a value, the history file is truncated, if necessary, by
removing the oldest entries, to contain no more than that number of lines. The default value is 500. The history file is also truncated to this
size after writing it when an interactive shell exits.
HISTIGNORE
A colon-separated list of patterns used to decide which command lines should be saved on the history list. Each pattern is anchored at the begin-
ning of the line and must match the complete line (no implicit `*' is appended). Each pattern is tested against the line after the checks speci-
fied by HISTCONTROL are applied. In addition to the normal shell pattern matching characters, `&' matches the previous history line. `&' may be
escaped using a backslash; the backslash is removed before attempting a match. The second and subsequent lines of a multi-line compound command
are not tested, and are added to the history regardless of the value of HISTIGNORE.
HISTSIZE
The number of commands to remember in the command history (see HISTORY below). The default value is 500.
To answer your questions directly:
No, there isn't a guarantee, since history can be disabled, some commands may not be stored (e.g. starting with a white space) and there may be a limit imposed on the history size.
As for the history size limitation: if you unset HISTSIZE
and HISTFILESIZE
:
unset HISTSIZE
unset HISTFILESIZE
you'll prevent the shell from truncating your history file. However, if you have an instance of a shell running that has these two variables set, it will truncate your history while exiting, so the solution is quite brittle. In case you absolutely must maintain long term shell history, you should not rely on shell and copy the files regularly (e.g., using a cron job) to a safe location.
History truncation always removes the oldest entries first as stated in the man page excerpt above.
Preserve bash history in multiple terminal windows
Add the following to your ~/.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, append to the history file and reread it
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
Arrow-UP key history in terminal
In bash, .bash_history
is a file which stores the commands history. HISTFILE
variable stores the location of command history file(aka .bash_history
).
$ echo $HISTFILE
/home/avinash/.bash_history
So the .bash_history
file is stored in my /home/$USER
(or ~
) directory.
Execute a command without keeping it in history
Start your command with a space and it won't be included in the history.
Be aware that this does require the environment variable $HISTCONTROL
to be set.
Check that the following command returns
ignorespace
orignoreboth
:echo $HISTCONTROL
To add the environment variable if missing, the following line can be added to the Bash profile. E.g., to file
%HOME/.bashrc
.export HISTCONTROL=ignorespace
After sourcing the profile again, space-prefixed commands will not be written to $HISTFILE
.
How can I see all of the bash history?
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.
How can I make bash_history update more often?
Add history -a
to your PROMPT_COMMAND
to update your saved history before each prompt.
PROMPT_COMMAND='history -a'
This should go in your .bashrc
file.
How to: Unlimited Bash/shell history?
Add this to your .bashrc
(Linux) or .bash_profile
(MacOS):
export HISTFILESIZE=
export HISTSIZE=
There you go, unlimited history. Currently I have 27000 entries :)
From man bash
:
If
HISTFILESIZE
is not set, no truncation is performed.
That means .bash_history
is never truncated
Also the same seems to apply to HISTSIZE
, although I couldn't find that documented.
Another neat feature I'm going to try is this:
If the
HISTTIMEFORMAT
variable is set, time stamps are written to the history file, marked with the history comment character, so they may be preserved across shell sessions, like the following:
export HISTTIMEFORMAT="%F %T "
Let me know if you have tried that already...
bash HISTSIZE vs. HISTFILESIZE?
Short answer:
HISTSIZE
is the number of lines or commands that are stored in memory in a history list while your bash session is ongoing.
HISTFILESIZE
is the number of lines or commands that (a) are allowed in the history file at startup time of a session, and (b) are stored in the history file at the end of your bash session for use in future sessions.
Notice the distinction between file
: on disk - and list
: in memory.
Long answer:
All the info above + some examples:
Example 1:HISTFILESIZE=10
and HISTSIZE=10
- You start your session.
- Your HISTFILE (file that stores your bash command history), is truncated to contain HISTFILESIZE=10 lines.
- You write 50 lines.
- At the end of your 50 commands, only commands 41 to 50 are in your history list, whose size is determined by HISTSIZE=10.
- You end your session.
- Assuming
histappend
is not enabled, commands 41 to 50 are saved to your HISTFILE which now has the 10 commands it held at the beginning plus the 10 newly written commands. - Your HISTFILE is truncated to contain HISTFILESIZE=10 lines.
- You now have 10 commands in your history - the last 10 that you just typed in the session you just finished.
- When you start a new session, you start over at step 1 with a HISTFILE of HISTFILESIZE=10.
Example 2:HISTFILESIZE=10
and HISTSIZE=5
- You start your session.
- Your HISTFILE (file that stores your bash command history), is truncated to contain at most HISTFILESIZE=10 lines.
- You write 50 lines.
- At the end of your 50 commands, only commands 46 to 50 are in your history list, whose size is determined by HISTSIZE=5.
- You end your session.
- Assuming
histappend
is not enabled, commands 46 to 50 are saved to your HISTFILE which now has the 10 commands it held at the beginning plus the 5 newly written commands. - Your HISTFILE is truncated to contain HISTFILESIZE=10 lines.
- You now have 10 commands in your history - 5 from a previous session and the last 5 that you just typed in the session you just finished.
- When you start a new session, you start over at step 1 with a HISTFILE of HISTFILESIZE=10.
Example 3:HISTFILESIZE=5
and HISTSIZE=10
- You start your session.
- Your HISTFILE (file that stores your bash command history), is truncated to contain at most HISTFILESIZE=5 lines.
- You write 50 lines.
- At the end of your 50 commands, only commands 41 to 50 are in your history list, whose size is determined by HISTSIZE=10.
- You end your session.
- Assuming
histappend
is not enabled, commands 41 to 50 are saved to your HISTFILE which now has the 5 commands it held at the beginning plus the 10 newly written commands. - Your HISTFILE is truncated to contain HISTFILESIZE=5 lines.
- You now have 5 commands in your history - the last 5 that you just typed in the session you just finished.
- When you start a new session, you start over at step 1 with a HISTFILE of HISTFILESIZE=5.
Info from elixir_sinari:
The history "file" is not updated as you type the commands. The
commands get stored in a "list" separately (accessed by the history
command). The number of these stored commands is controlled by
HISTSIZE value. When the shell (interactive) exits, the last
$HISTSIZE lines are copied/appended to $HISTFILE from that "list".
If HISTFILESIZE is set, then after this operation, it is ensured
that only $HISTFILESIZE lines (latest) exist in $HISTFILE . And
when the shell starts, the "list" is initialized from $HISTFILE up to
a maximum of $HISTSIZE commands.
And from the man bash
page:
The value
of the HISTSIZE variable is used as the number of commands to save in a history list. The text of the last HISTSIZE commands
(default 500) is saved. (...)On startup, the history is initialized from the file named by the variable HISTFILE (default ~/.bash_history). The file named by
the value of HISTFILE is
truncated, if necessary, to contain no more than the number of lines specified by the value of HISTFILESIZE. (...) When an interactive shell exits, the last $HISTSIZE lines
are copied from the history
list to $HISTFILE. If the histappend shell option is enabled (see the description of shopt under SHELL BUILTIN COMMANDS below), the
lines are appended to the
history file, otherwise the history file is overwritten. If HISTFILE is unset, or if the history file is unwritable, the history
is not saved. (...) After saving the history, the
history file is truncated
to contain no more than HISTFILESIZE lines. If HISTFILESIZE is not set, no truncation is performed.
How do I prevent commands from showing up in Bash history?
If you've set the HISTCONTROL
environment variable to ignoreboth
(which is usually set by default), commands with a leading space character will not be stored in the history (as well as duplicates).
For example:
$ HISTCONTROL=ignoreboth
$ echo test1
$ echo test2
$ history | tail -n2
1015 echo test1
1016 history | tail -n2
Here is what man bash
says:
HISTCONTROL
A colon-separated list of values controlling how commands are saved on the history list. If the list of values includes
ignorespace
, lines which begin with a space character are not saved in the history list. A value ofignoredups
causes lines matching the previous history entry to not be saved. A value ofignoreboth
is shorthand forignorespace
andignoredups
. A value oferasedups
causes all previous lines matching the current line to be removed from the history list before that line is saved. Any value not in the above list is ignored. IfHISTCONTROL
is unset, or does not include a valid value, all lines read by the shell parser are saved on the history list, subject to the value ofHISTIGNORE
. The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value ofHISTCONTROL
.
See also:
- Why is bash not storing commands that start with spaces? at unix SE
- Why does bash have a HISTCONTROL=ignorespace option? at unix SE
Related Topics
Why I Am Not Getting Signal Sigkill on Kill -9 Command in Bash
Eclipse Doesn't Use The Path Set in .Bashrc
Does File ".Bash_History" Always Record Every Command I Ever Issue
What Ncurses Frameworks Are Available for Bash
Test If String Has Non Whitespace Characters in Bash
How to Give File Permission to a Specific User in a Group
Correcting The Gcc Command Line Ordering Using Automake
Getting Function Arguments Using Kprobes
How to Manually Install The Eclipse-Cdt Plugin from an Archive/Zip on Ubuntu
How to Redirect Http to Https Using Gcp Load Balancer
Adding New System Call to Linux Kernel 3.13 on 64 Bit System
Running a Script Just Before Installation of Debian Finishes Using Preseed
Are Mlock()-Ed Pages Static, or Can They Be Moved in Physical Ram
Is Wget or Similar Programs Always Available on Posix Systems