
Understanding Bash History - Altreus
http://symkat.com/90/understanding-bash-history/
======
koeselitz
Heh. This is funny timing, as .bash_history made me feel like an idiot just
yesterday morning.

I was sitting here between queries and I thought 'y'know, all I ever do with
history is grep for things. I wonder what else I can do?' When I want to learn
about something quick, I usually start with the built-in help; so I did

history --help

The built-in help for history, unfortunately, is woefully inadequate; this was
the output:

history: usage: history [-c] [-d offset] [n] or history -awrn [filename] or
history -ps arg [arg...]

I said to myself: "Hmm. Wonder what those do?" -- and in a moment of bash
stupidity, I thought: "well, let's try it!"

history -c

There's no output from that command, but it didn't take long to figure out
what it does. It _deletes your entire bash history_ , clearing the history in
RAM and emptying .bash_history.

Since I use history _all the time_ , I panicked. Holy crap! What have I done?
I spent a few minutes internalizing the obvious lesson that everybody knows -
_never run commands without knowing them first_. Thankfully, though, I had
another bash open at the time. And after I'd beaten myself up over it, I
thought for a moment, jumped over to the other shell, and did:

cd && history | cut -c 8- >> .bash_history

... because (after all) the evil, evil history -c command doesn't kill the
history from RAM in _other_ shells.

Lucky me.

~~~
there
_The built-in help for history, unfortunately, is woefully inadequate; this
was the output:_

i always wondered whether linux had such terrible man pages because nobody
read them, or whether nobody read them because they were so terrible.

~~~
1amzave
Well, since 'history' is a shell builtin, the thing to do would be 'help
history', which actually gives a pretty thorough explanation of it. (And it's
also explained pretty fully if you look at the actual man page for bash.) What
the grandparent commenter saw was in fact just the brief "you invoked this
command wrong" synopsis message, since '--help' isn't a flag recognized by the
'history' command (assuming his version of bash behaves similarly to mine).

Sure, there are some more obscure, less-commonly-used commands that are poorly
documented, but for the basic stuff (and yes, that includes bash), I've found
man pages to generally be a pretty good source of information.

~~~
koeselitz
Yes, the actual linux documentations are actually very good. I live on a
server with hacked-together shell commands that are badly-documented, so I'm
in the bad habit of doing the --help thing (the default around here).

The man pages are indeed very good. It's also worth noting that the Gnu people
tend to prefer info pages - and 'history' is traditionally a Gnu-maintained
command (as part of binutils) - so you'll get the absolute best documetation I
know of (long explanations, interesting permutations, obscure hacks) if you
do:

info history

------
ggchappell
I use history a fair amount, and I've noticed an issue that none of these
articles mention.

For history to be useful, you need to be able to reuse previous commands
without giving them much thought; in the time it takes to think in detail
about a command, you usually could have typed a new one without using history.
As a result, commands that are reused via the history mechanism need to be
"safe", with no hidden pitfalls.

For example, I use "find" a lot. A normal thing to do with "find" is to get a
list of files to delete. Now, I could do that with "find ... -exec rm" or
"find ... xargs ... rm", but that leaves me with an unsafe "find" command in
my history, just waiting to bite me when I try to reuse it. If, some time
later, I type "!fi" without thinking much about it, I might end up deleting
some random files. Not good.

My solution, in this particular case, is _never_ to do "find ... rm" on a
single line. To remove a list produced by "find", I do "find ..." and then "rm
`!!`". That runs the "find" command twice, of course, but the second time,
everything has been cached, so it's very fast. (The real disadvantage is that
the delay -- for the first "find" -- occurs in the middle of what is
conceptually a single operation: after I've typed the "find", but before the
"rm".)

So, has anyone else run into this issue? Thoughts? Other ways of dealing with
it?

~~~
ikitat
find ...

!! -delete

~~~
ggchappell
Ah, didn't know about that one. Thanx.

(But it still doesn't address the main issue.)

~~~
ikitat
HISTCONTROL="ignorespace"

now you can keep a given command from history

find ...

<space>!! -delete

~~~
ggchappell
That's a nice feature.

Now it remains to be seen whether I can train myself to always precede
"unsafe" find commands with a blank.

------
keyist
While what is covered is very well presented, post doesn't mention `shopt -s
histappend`, which is one of the most important things to note when dealing
with history in bash.

Also useful: you can append :s/foo/bar to bang commands to substitute once,
:gs/foo/bar to substitute globally. `man bash` History Expansion section has
the other options under subheading 'Modifiers'.

I highly recommend the following resource -- it's what really got me saving
keystrokes:

<http://www.ukuug.org/events/linux2003/papers/bash_tips/>

------
simoncoggins
I learnt something handy in BASH recently - operate-and-get-next (Ctrl-o). If
you type:

    
    
      $ echo one
      one
      $ echo two
      two
      $ echo three
      three
    

Then up-arrow back to 'echo one'. Then press Ctrl-o instead of enter it will
execute the command and display the following one in your history ('echo two'
in this case).

Very handy for replaying a series of commands.

<http://www.faqs.org/docs/bashman/bashref_101.html>

~~~
ryanf
This is in the man page for bash on Snow Leopard, but it doesn't seem to
actually work. Does anyone know why?

~~~
simoncoggins
There's a solution here:

[http://hintsforums.macworld.com/archive/index.php/t-82501.ht...](http://hintsforums.macworld.com/archive/index.php/t-82501.html)

'stty -iexten' fixed it for me on my Mac.

------
cmurphycode
Here are some of my other favorites:

^foo^bar replaces the foo in the last command with bar

example: less setup.conf, ^less^vim

alt+. recalls the last argument of the last command (in emacs mode, anyway)

example: less setup.conf, vim alt+.

As mentioned, Ctrl+R is great for history searching. Repeatedly pressing
Ctrl+R goes to the next result, and you can use the arrow keys to edit.

cd - goes to the last directory. It handles most of the use cases for pushd
and popd.

~~~
koeselitz
As far as these little shorthands go, you've left out the one I use most all
day long; the ever-handy !:-, which means 'the last command minus the final
argument':

$ cat ~/my_huge_dataset.csv | tr '\|' ',' >> testing.csv

$ !:- for_real_this_time.csv

>> cat ~/my_huge_dataset.csv | tr '\|' ',' >> for_real_this_time.csv

$

This is really, really handy for me - particularly in two situations: first,
when (like above) I'm testing a command by outputting to a random off-server
file first; and second (the more often) when I'm running the exact same
process on a dozen different files, just pasting the filenames onto the
command line. It's really handy to be able to use !:- all the way down for
every one.

Oh, and theres's also this: !! - which means 'the last command exactly.' That
can be handy, too:

$ rm /usr/lib/libutil.so

>> m: cannot remove `libutil.so': Permission denied

$ sudo !!

$

~~~
cmurphycode
I like the !:-, even though it's super ugly. It's the perfect complement to
alt+. !! is a classic, but the article mentions it.

------
nitrogen
I like mapping page up and page down to history-search-backward and history-
search-forward in /etc/inputrc or ~/.inputrc. It works much like the bang
commands. Ubuntu and Debian have the appropriate lines commented out; other
distros might enable such a mapping by default (Mandriva did when I used it
last).

    
    
      "\e[5~":        history-search-backward
      "\e[6~":        history-search-forward
    

Some other useful entries:

    
    
      # ctrl-left, ctrl-right
      "\e[1;5C":forward-word
      "\e[1;5D":backward-word
      "\e[5C":forward-word
      "\e[5D":backward-word
      "\e\e[C":forward-word
      "\e\e[D":backward-word

------
bpodgursky
Mentioned in the comments, but another extremely useful feature is if you type
ctrl+r and start typing a command, it will give you the last command you ran
that contains that substring.

~~~
billswift
This is the main way I use the history, other than just cycling through the
last few commands with the up arrow. I've just never found the bang commands
useful enough to be worth remembering for the relatively few times they
_would_ be useful. ADDED: Note that I have a pretty large .aliases file that I
have profile run when I log in. Any complicated command lines that I run at
all frequently get aliased and added to the list. Or for longer lines I
convert them to a script in my $HOME/bin.

------
logic
Since everyone's sharing their bash history tips here, I thought I'd throw one
out. I've taken to tossing the following lines in my root user's .bashrc over
the last few years (which I adapted from a colleague years ago):

    
    
      [ ! -d $HOME/.history ] && mkdir $HOME/.history
      set -- `/usr/bin/who -m`
      HISTFILE="$HOME/.history/`/bin/date +%Y-%m-%d.%T`.`/bin/hostname -s`.$$.$1"
    

You end up with a filename something like:

    
    
      2010-09-17.13:53:27.foohost.14379.logic
    

The idea is that each shell session gets it's own history file, and the files
are kept "indefinitely"; ie. whenever I manually get around to cleaning them
up. Keeping that history around is cheap (we're talking about a few megabytes
over the life of a given system), and can be invaluable in figuring out the
how and why of a particular change even months later.

It also serves the purpose of making a best-effort attempt at gathering who
"owned" that session (ie. who su'd to root); with multiple admins, this can be
pretty handy. It's easily bypassed (and console logins will just show up as
"root"), so using this as any kind of audit system would be ridiculous; it's
just a useful way of going back in time to see who did what (usually looking
of work I did myself, to see how/why I might have made a particular change
months ago).

The one downside: you lose cross-session history. In practice, especially with
multiple users accessing a shared account (multiple admins, etc), this hasn't
really bothered me much, as getting someone else's history is annoying anyway.
But, some people lean pretty hard on their bash history, and I definitely
wouldn't do this for a personal account. (There, I'd just do "shopt -s
histappend".)

------
phaedrus
I used Linux for years without knowing about the bash history file (though I
knew about hitting the up arrow). As soon as I discovered this file, I looked
up how to set it to save all my history forever without rollover - what a good
resource it would be to have all the commands I've ever used!

Anyone know of a utility for saving annotations about the bash history lines?
(Date, comments, current directory, etc.?)

~~~
EdiX
[http://stackoverflow.com/questions/945288/saving-current-
dir...](http://stackoverflow.com/questions/945288/saving-current-directory-to-
bash-history/960684)

------
amackera
Thanks for the link! I've been looking for a writeup on bash history features
for a while. These things are very useful day-to-day.

------
Tyr42
I learned a lot from this article. It is very useful for novices such as
myself. My uparrow key thanks you for writing this.

~~~
billybob
If you're hitting the up arrow more than a few times, you could easily see
search your history instead with "history | grep somestring", or, as someone
else mentioned, Ctrl+R and start typing a command.

------
xyzzyz
Slightly misleading title. I expected a tale of ancient hackers, writing code
and making decisions, some of which were good, and others that today we
regret.

