Linux Tips: take control of your bash_history
I spend most of my time working in front of a black and white terminal of remote SSH connections to various servers. This means that I use bash (as my preferred shell) most of the day. And bash history is a very important feature of bash that saves me much time by recalling previous commands I have typed. Here are some tricks on how you can optimize with some simple configurations settings the usage your bash history.
1. Don’t save duplicates:
This is my favorite…
HISTCONTROL=ignoreboththis causes any lines matching the previous history entry not to be saved.
Other options for HISTCONTROL: ignorespace, lines which begin with a space character are not saved in the history list; erasedups causes all previous lines matching the current line to be removed from the history list before that line is saved.
2. Size of the history:
HISTSIZE: The number of commands to remember in the command history. The default value is 500.
HISTSIZE=500You can set this to 0 and disable the usage of the history file.
3. Others:
HISTFILE: The name of the file in which command history is saved. The default value is ~/.bash_history.
HISTIGNORE: A colon-separated list of patterns used to decide which command lines should be saved on the history list.
How do you set these options? Either export them in your environment in your personal bash configuration file (~/.bashrc) or in the global bash configuration file (/etc/bash.bashrc). The name of the configuration files can depend from your Linux distribution and bash version (the ones included are from Debian Linux), but you can always see your particular options using man bash. So, you can add in your configuration files the parameters you want like this:
export HISTCONTROL=ignoreboth
export HISTSIZE=500You will need to restart your bash session in order to activate the settings. You can check if your configuration were entered correctly by typing env at the command prompt. If you don’t see your configuration in the environment variables than you have done something wrong. If you see your configuration option, then all is ok, and your setting is active already.
Note: to my students (Bogdan and Alin) that attend my Linux Sysadmin course, I hope that this responds your question. Let me know if you have any other questions regarding this issue.
Here is a great note by one Digg user: burke
“the most efficent way to search your history is to hit Ctrl R and type the start of the command. It will autocomplete as soon as there’s a match to a history entry, then you just hit enter”
>







16th May 2006, 08:38
how can I increase the amount of bash screen pages I can scroll back through ? the HISTSIZE only effects the number of commands not the screens.
16th May 2006, 08:42
bubba, what do you mean by “bash screen pages”?
16th May 2006, 10:01
Bubba, I don’t think you can. That’s called scrollback, and the amount you get is based on video memory, since that’s where it’s stored. What you can do is run “screen”, which is a really neat program that allows you to have an unlimited scrollback buffer, among other things like terminal multiplexing.
16th May 2006, 10:01
I can only assume he means the amount you can scroll back and read in a terminal, which has nothing to do with bash. That’s controlled by whatever terminal emulator you’re using. bash has no knowledge of past output from commands.
16th May 2006, 10:06
Really interesting article.
Thanks!
16th May 2006, 10:16
Very helpful indeed. I would try to use [Ctrl-R] as much as possible now.
16th May 2006, 12:56
With xterm you can set the number of lines of scrollback with the -sl option. I personally use `xterm -fg white -bg black -vb -sl 2048`
16th May 2006, 14:39
How restart bash w/o logging out completely?
16th May 2006, 16:00
I often run several aterm’s, each of which keep an individual bash history. If I close them all, and reopen, I lose all but one of the histories. Is there some way to restore or merge the histories from multiple terminals?
16th May 2006, 16:03
i like the link to /dev/null, but the syntax is backwards.
it should be:
ln -sf /dev/null ~/.bash_history
also, setting the removedup with this link seemed to cause problems, i assume because bash was trying to remove dups from my history which is now /dev/null.
16th May 2006, 16:47
to dlist: “How restart bash w/o logging out completely?”
You just have to export the configurations that you want on your current shell session:
$export HISTCONTROL=ignoreboth
$export HISTSIZE=500
You can check if they are entered correctly with: $env
(still this will not save them on the next session if you have not placed them in the startup bash files).
16th May 2006, 16:57
to Roman: “I often run several aterm’s, each of which keep an individual bash history. If I close them all, and reopen, I lose all but one of the histories. Is there some way to restore or merge the histories from multiple terminals?”
This happens because the commands are kept in a memory buffer and are normally written to the history file only on the session exit.
You should check out the history built in command. For ex.
history -a
Append the new history lines (history lines entered since the beginning of the current Bash session) to the history file.
For more check the manual page, as there are more useful options, like:
history -c (clear the history)
history -w (write to the file – overwrite!), etc.
16th May 2006, 17:32
also there is a command to switch betwwn the current and prev. used directory .. i dont remeber it..
16th May 2006, 18:58
To Roman: “I often run several aterm’s, each of which keep an individual bash history. If I close them all, and reopen, I lose all but one of the histories. Is there some way to restore or merge the histories from multiple terminals?”
I keep track of how many terminals I have open by “touch”ing a file in a directory, then set my HISTFILE accordingly. Here’s the relevent code (this is from ksh, but I’ve gotten to work for bash, I just don’t have access to the bash one right now):
In .profile:
export NEWWINDOW=1
In .kshrc:
if [[ ${NEWWINDOW:-0} -ne 0 && `tty` != "not a tty" ]]; then
export PS1=’${_sh:+$_sh.}’`hostname -s`’| $PWD: ‘
export THISWIN=1
integer THISWIN
while [ -f $HOME/.windows/win$THISWIN ]; do
THISWIN=$THISWIN+1
done
touch $HOME/.windows/win$THISWIN
trap “rm $HOME/.windows/win$THISWIN” 0
export HISTFILE=$HOME/.histories/.ksh_hist.$THISWIN.0
export HISTSIZE=512
unset _sh # just to make sure we don’t get a “0.” in front of the prompt.
unset NEWWINDOW
else
# Not in a new window
#### Ok, we are a shell in an existing window.
#### Increment the number of shells before current shell.
let _sh=${_sh:-0}+1
export _sh
#### Set up the history file for this shell.
export HISTFILE=$HOME/.histories/.ksh_hist.$THISWIN.$_sh
fi
With this, I will get a different history for each window. Plus, I’ll get a different history for each sub-shell. If you’re in vi, and shell out, your history is kept separate from your main history. And just to keep things clear, the prompt will show the “shell level” so you know you’re not at your login shell. I also add in a “set -o ignoreeof” inside the “if NEWWINDOW”. That way, I don’t accidentally close the window of my login shell.
Bash also has SHLVL (I think that’s the name), which you can set “_sh” to (might have to do some math on it). Some of this code is pretty old, so it might not be the best way to do it. But, it works so I didn’t feel the need to muck with it.
to ashish: “also there is a command to switch betwwn the current and prev. used directory .. i dont remeber it..”
You can do “cd -” to switch between the last 2 directories. I’ve also recently discovered this (might be a ksh only thing):
In directory /home/softdev/v1.23/foo/bar, but need to cd to /home/softdev/v2.34/foo/bar, you can do that with this:
cd v1.23 v2.34
16th May 2006, 20:56
Didn’t I read something about Bash 3.0 having a feature to date the .bash_history file?
17th May 2006, 00:21
Re multiple windows losing history:
You know you can just tell bash to append rather than overwrite the history file on exit, right?
shopt -s histappend
17th May 2006, 11:47
$ alias hg=”history | egrep”
I like to set this ‘hg’ shortcut so i can search my bash history (including current buffer) for a command i ran recently that took ages to work out all the right options, arguments, etc. eg “hg smbmount”, then use “!” where is the history number, which saves typing it all again.
17th May 2006, 11:50
that last bit got mangled cos the greater-than and less-than chars got taken out. it should have read something like:
eg “hg smbmount”, then use “!NNN” where NNN is the history number, which saves typing it all again.
17th May 2006, 22:57
To ashish, the standard bash command to return to the previous directory is “cd -”. In fact, “-” is an alias to the previous directory generally . So you can type “cp * ~-” to copy all files in the current dir to the previous dir.
18th May 2006, 02:18
#11 dlist what you’re looking for is ‘exec bash’
#16 ashish what you’re looking for is ‘pushd’ and ‘popd’
18th May 2006, 03:12
Dont think any1 mentioned it yet, but you can treat your bash history like a big vi buffer by:
set -o vi
Then you can move around in and edit your command history like a vi file. I guess you can do the same with emacs?
18th May 2006, 07:22
Screen scrollback setting:
in ~/.screenrc
defscrollback 10000
for example
19th May 2006, 22:02
You should add that pressing ctrl+r many times will search for previous commands.
25th May 2006, 22:24
how can i change the command prompt line? like instead of root@localdomain.com and change it to something like myname@localdomain.com…
25th May 2006, 23:02
gaga, the command prompt is configured by the shell variable PS1.
I will write a short story in the next days about how I like to set my prompt.
Regarding your question: you can do this in an active session by exporting the PS1 variable, like:
export PS1=”\u@\h [\w]# ”
where: \u is the current username, \h is the hostname, and \w the working directory. If you want something particular you just make it as you like it…
export PS1=”gaga@\h# ”
Lookout for my article on this that will contain some cool examples on what you can do with the command prompt.
ps. remember that if you want to make it permanent you will need to save it in the bash initialization file (user or system, whatever you need).
7th August 2006, 20:18
You don’t need to restart bash to activate settings, just source the config file:
> . ~/.bashrc
1st September 2006, 12:03
[...] Here are some tricks on how you can optimize with some simple configurations settings, the usage your bash historyread more | digg story [...]
15th November 2006, 12:56
And don’t forget “fc” to open the last command in a text editor (usually vi) but depends on your EDITOR env variable.
You can then edit and change the command
comes quite handy!
5th December 2006, 07:55
Another history variable I like to set in bash 3.0 or greater (or my patched bash from 2.05b which also has debugging support) is HISTTIMEFORMAT. This gives a timestamped history.
When a friend’s box was once hacked, seeing the timestamps helped sort out when the box was hacked and which person did what.
The setting I use is
export HISTTIMEFORMAT=’%a %T ‘
which is compatible with the tcsh.
But no doubt others will prefer something else. There are situations when I’d prefer the less cute day of the week in favor of a simple date, even though it is longer. But you can change this value on the fly and see basically the same timestamp presented in alternative formats.
The important thing at least in bash 3.x is that this variable be set to something, or else no time entry is added to the history file. (In the patched 2.05b, timestamping ithe history always happens.)
The format string really of that variable is just passed to the C library strftime(). See man 3 strftime for what the various time specifiers are and what they mean.
13th February 2007, 01:59
@ R. Bernstein
and
@ Any others that might know
Anyone got any ideas on how to add more info to the history file, specifically which terminal did what?
Imagine multiple root users on a system….something like:
pts/0: ls -la
pts/1: ps -aux
A timestamp to that would be great, but I am forced into bash 2.05b currently so I have already devised a timestamp hack for that:
echo “$(who -m) logged in at $(date)” >> /root/.bash_history
function _exit()
{
echo “$(who -m) logged out at $(date)” >> /root/.bash_history
}
trap _exit EXIT
This inserts the the user who logged in and when they log out into bash history, but its not really complete without some sort of verification of which user issued the commands that appear in the history file because sometimes different terminal seem to get consolidated into the history file. Any idears?
Hope my script helps others.
28th February 2007, 08:54
hello marius,
I read something about “Linux Sysadmin course” in your post above and although this might be an old post (I can’t find a date) I am very much interested so if you can give me some info on where one could attend such a course in Sibiu…
5th March 2007, 14:28
ovidiu,
This was about a course I held for a private company’s employees. The course was held at the company’s location (theoretical and practical) after regular working hours.
25th April 2007, 08:13
To seach in hystory I always decomment the following lines from /etc/inputrc:
# alternate mappings for “page up” and “page down” to search the history
“\e[5~”: history-search-backward
“\e[6~”: history-search-forward
6th May 2007, 17:38
You should add that pressing ctrl+r many times will search for previous commands.
25th May 2007, 04:18
[...] Linux Tips: take control of your bash_history (tags: linux bash cli) [...]
6th August 2007, 08:55
Screen scrollback setting:
14th August 2007, 04:12
Hello ,
how i will see the history of the terminal ? like i login form tty1 & tty2
Now i want to see tty2 history ?
How ?
24th August 2007, 07:03
Why there is no date and time in the lines of .bash_history ?
15th October 2007, 12:22
[...] e.g. stores 1 instance of ssh xxx.xxx.xxx.xxx instead of 7. So I did a little google and found this little gem. Thanks to this, my life is a little bit [...]
19th October 2007, 17:31
How do you set command completion from the history? For example, you can type ‘find’ then each time you hit the up-arrow, a previous ‘find’ line in your history is completed. When you get the right one, you just hit enter.
23rd November 2007, 20:44
Here are two useful snippets from my .bashrc:
# save your history week-by-week
export HISTFILE=$HOME/.history-bash/”hist-`date +%Y-%W`.hist”
if [[ ! -f $HISTFILE ]]; then
# We’re starting a new history file. Find the previous (biggest date) histfile
LASTHIST=~/.history-bash/`ls -1tr ~/.history-bash/ | tail -1`;
if [[ -f "$LASTHIST" ]]; then
# and stock our new history with the last 500 lines of last week’s file
tail -500 “$LASTHIST” > $HISTFILE
# Write a divider to identify where the prior day’s session history ends
echo “####### `date +%Y-%W-%w` : `date` #######” >> $HISTFILE
fi
fi
# Now toss the current history file onto the history stack (if you hit the up arrow
# you’ll see the last thing you typed before your previous log-out)
history -n $HISTFILE
# Hard drives and memory are cheap. Keep 10,000 lines of history and
export HISTSIZE=10000
# don’t limit the size of the history file.
unset HISTFILESIZE
# Here are some perhaps helpful commands to accompany those
# command to pull in the contents of the history file (good for pulling history
# from one terminal to the next)
alias histup=’history -n $HISTFILE’
# search (using perl regexp syntax) your entire history
function histgrep()
{
grep -P $@ ~/.history-bash/*
}
17th January 2008, 13:05
Thx for these really useful hints. I myself am a zsh-man, but my
colleagues insist on using bash. I migrated some of the most useful
zsh-features to their .bashrc but what I couldn’t find is an equivalent of
INC_APPEND_HISTORY. Bash only writes its history when you exit.
This makes it really hard in a shared user environment, especially because
many seldom logout.
Anyone here knows an alternative to INC_APPEND_HISTORY for bash?
Or how to implement it using hooks or something like that?
Thanks,
Andy.
17th January 2008, 20:51
Andy: I think this forum post I have answered last month, might help you also:
http://forum.ducea.com/discussion/23/bash-history-for-multiple-session/
- Marius -
18th January 2008, 01:09
Thanks a lot, Marius!
I took out the “history -n” and works like a charm now!
Almost as good as with zsh now.
Andy.
12th March 2008, 18:36
[...] Here are a couple of tips for more effective use of your Bash command history. I think the Ctrl-R trick will save me a lot of typing. [...]
2nd April 2008, 15:14
which is a really neat program that allows you to have an unlimited scrollback buffer, among other things like terminal multiplexing.
15th July 2008, 10:41
my problem solved thanks alot
regards
18th August 2008, 15:46
[...] Knowing history event numbers is useful: [...]
28th October 2008, 02:27
Bash is the shell widely used by many sysadmins. You can disable the usage of bash history in case you don’t want others to see what you have been typing
.
12th November 2008, 20:13
Does anybody have a cool way to delete lines from the history file
using pattern matching or regular expressions ?
17th December 2008, 09:31
I can’t believe I didn’t know about the Ctrl-R thing. Think of all the keystrokes I’ve wasted over the years! Thanks a lot for this tip, I KNEW there had to be a better way than history | grep…
1st January 2009, 05:42
http://digg.com/linux_unix/tagging_your_bash_history_entries_for_use_with
This shows how to tag all your commands in .bash_history and the use + tag to reuse common commands.
12th April 2009, 19:40
[...] Linux Tips: take control of your bash_history [...]
17th September 2009, 10:57
[...] How to suspend and hibernate a laptop under Linux; damn small linux; fvwm howto; fluxbox howto; take control of your bash history; bash shell shortcuts; pybackpack; Triggering software events from hardware changes with HAL and [...]
27th February 2010, 01:14
‘ignoreboth’ is ‘ignoredups’ + ‘ignorespace’