Does File ".Bash_History" Always Record Every Command I Ever Issue

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 or
    ignoreboth:

     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

  1. You start your session.
  2. Your HISTFILE (file that stores your bash command history), is truncated to contain HISTFILESIZE=10 lines.
  3. You write 50 lines.
  4. At the end of your 50 commands, only commands 41 to 50 are in your history list, whose size is determined by HISTSIZE=10.
  5. You end your session.
  6. 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.
  7. Your HISTFILE is truncated to contain HISTFILESIZE=10 lines.
  8. You now have 10 commands in your history - the last 10 that you just typed in the session you just finished.
  9. 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

  1. You start your session.
  2. Your HISTFILE (file that stores your bash command history), is truncated to contain at most HISTFILESIZE=10 lines.
  3. You write 50 lines.
  4. At the end of your 50 commands, only commands 46 to 50 are in your history list, whose size is determined by HISTSIZE=5.
  5. You end your session.
  6. 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.
  7. Your HISTFILE is truncated to contain HISTFILESIZE=10 lines.
  8. 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.
  9. 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

  1. You start your session.
  2. Your HISTFILE (file that stores your bash command history), is truncated to contain at most HISTFILESIZE=5 lines.
  3. You write 50 lines.
  4. At the end of your 50 commands, only commands 41 to 50 are in your history list, whose size is determined by HISTSIZE=10.
  5. You end your session.
  6. 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.
  7. Your HISTFILE is truncated to contain HISTFILESIZE=5 lines.
  8. You now have 5 commands in your history - the last 5 that you just typed in the session you just finished.
  9. 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 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.

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



Leave a reply



Submit