6 ms·
Understanding Bash History
- xyzzyz 16y agoSlightly 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.
- Tyr42 16y agoI learned a lot from this article. It is very useful for novices such as myself. My uparrow key thanks you for writing this.
- billybob 16y agoIf 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.
- bpodgursky 16y agoMentioned 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 16y agoThis 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.
- amackera 16y agoThanks 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.
- cmurphycode 16y agoHere 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 16y agoAs 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 16y agoI like the !:-, even though it's super ugly. It's the perfect complement to alt+. !! is a classic, but the article mentions it.
- keyist 16y agoWhile 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/ http://www.ukuug.org/events/linux2003/papers/bash_tips/
- phaedrus 16y agoI 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 16y agohttp://stackoverflow.com/questions/945288/saving-current-directory-to-bash-history/960684 http://stackoverflow.com/questions/945288/saving-current-dir...
- koeselitz 16y agoHeh. 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 16y agoThe 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 16y agoWell, 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.
- nitrogen 16y agoI 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
- simoncoggins 16y agoI 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 http://www.faqs.org/docs/bashman/bashref_101.html
- ryanf 16y agoThis is in the man page for bash on Snow Leopard, but it doesn't seem to actually work. Does anyone know why?
- simoncoggins 16y agoThere's a solution here: http://hintsforums.macworld.com/archive/index.php/t-82501.html http://hintsforums.macworld.com/archive/index.php/t-82501.ht... 'stty -iexten' fixed it for me on my Mac.
- ggchappell 16y agoI 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 16y agofind ... !! -delete
- ggchappell 16y agoAh, didn't know about that one. Thanx. (But it still doesn't address the main issue.)
- ikitat 16y agoHISTCONTROL="ignorespace" now you can keep a given command from history find ... <space>!! -delete
- ggchappell 16y agoThat's a nice feature. Now it remains to be seen whether I can train myself to always precede "unsafe" find commands with a blank.
- logic 16y agoSince 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".)