> The last few versions of MacOS have introduced random fires which burn down your .bash_history, leaving this occasional sad, sad result:
$ wc -l .bash_history 0
I think there is some context missing here... Why is your .bash_history getting cropped? Was there a change in some default configuration of your Terminal app on update perhaps?
On a side-note I really think fish-shell really got history-recall and completion right, which is really the one thing that keeps me using it even if I still script in bash.
I'm a programmer and an historian. So the title of this entry gave me a wrong first impression: there are more people like me! I'm not alone! Imagine the disappointment... ;)
Something that has been serving me well over the years:
export PROMPT_COMMAND='if [ "$(id -u)" -ne 0 ]; then echo "$(date "+%Y-%m-%d.%H:%M:%S") $(pwd) $(history 1)" >> ~/.logs/bash-history-$(date "+%Y-%m-%d").log; fi'
Creates a daily log file of every command entered. Searching for anything is a simple grep command.
What an interesting contrast in attitudes toward privacy:
He makes an extraordinary effort to maintain his bash history whereas I jump through hoops to delete my history (on logout using a .bash_logout file).
I also set my browser to maintain no history, disable saving of chats in everything, delete caches wherever possible, and generally wish that apps and programs had an option to save zero information on exit!
If I want "history" beyond a session, I'll explicitly make a shell alias for a command that I want to remember, or make bookmark for a site I want to revisit, etc.
https://news.ycombinator.com/item?id=10695305
^ In this comment I explained how I just have all my bash history logged directly into SQLite.
Shameless plug, my version of YABHA (yet another bash history app): https://github.com/andmarios/bashistdb
Written in go, uses sqlite and can work locally or remotely. In the latter case you can send history from many accounts and search globally. Transport encryption is based on NaCl. One binary serves all roles.
Doesn't store other information than command line and time but this is what I need most of time.
The main pain point behind its creation was searching in history. There is a global flag (search in all accounts, -g), the wild card is SQL's wild card (%). Less frequently used but very helpful, content search (-A, -B, -C, like grep). Also regexp is supported though very rarely is needed.
I've been curating my .bash_history for years; it's a great way to recall all those contorted commands which come in handy every year or so:
https://github.com/l0b0/tilde/blob/master/.bash_history
Git GUI plus a simple Makefile target to sort it is all the tooling necessary:
https://github.com/l0b0/tilde/blob/b16794f2ff209a6bc64813f02...
When I was first programming and into UNIX it was the norm amongst those I was learning from that you'd symlink your history file to /dev/null
This had a few advantages which might not be immediately apparent. The most obvious is that you remove the risk of leaking private or sensitive data.
The second is that searching your history is an anti-pattern. If there is a command you can't remember, or if there is a group of commands you need to accomplish a task, you should be writing shell scripts
My ~/bin folder has 104 files in it[0] and is in git, is available wherever I log in, whichever tty I have open and has a much better taxonomy than 'search for part of command' based on doing tasks. The same can't be said for history files.
[0] at its peak when I was a BSD and RHEL user it would have been more files but i've recently switched to Alpine.
If this article appeals to you, here's a few little items that you may find handy (cf. bash(1)):
$ shopt -s histappend
$ export HISTTIMEFORMAT="%F %T: "
$ export HISTCONTROL=ignoreboth
$ export HISTFILESIZE=-1
$ export HISTSIZE=-1
Also, maybe you should consider backing up ~/.bash_history occasionally?Odd that your history is being cleared out, it's never happened to me.
I always keep my own history of every command I ever run. I've moved this from computer to computer. So I can look back years in the past and see what I've done.
case "$TERM" in
xterm*|rxvt*)
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}\007"; echo `date +"%b %e %Y %H:%M:%S"` $? \"`history 1|cut -c7-`\" in `pwd` >> ~/.audit'
;;
*)
;;
esac
It seems like Bash history was made for a time that is long gone, and has not been fixed to work in a modern environment. I have tons of shells open, and I cannot promise to close them carefully and sequentially.
Instead I found this to add to my .bashrc:
pcmd='if [ "$(id -u)" -ne 0 ]; then echo "$(pwd) $(history 1)" >> ~/.logs/bash-history-$(date "+%Y-%m-%d").log; fi'
PROMPT_COMMAND="$PROMPT_COMMAND;$pcmd"
It keeps all commands from all open shells in dated log files that I can grep through when Ctrl+R fails me.Just be aware that if someone hacks into your PC they can see every command you have ever run, including any passwords accidentally pasted.
For anyone wondering, the correct way to do that cowsay command is `figlet moo |cowsay -n`
Last time my .zsh_history was randomly emptied on me I was so so stranded - I felt helpless.
I've now doubled-down on it and actually store lots of todo notes or receipt numbers or random snippets like that in my shell history as comments. It's just always there :-)
And fortunately btrfs snapshots (and one time, a backup from a laptop migration...) have saved me form losing it for a long time now :-)
Shell history is awesome, I'm always really intrigued when I see someone like a sysadmin who doesn't use shell history very well (read, at all...)
Alternatively, you can use ZSH and not lose history, even better, have history work simultaneously in multiple terminal windows simultaneously without closing the window to save/read the history of other windows. http://ohmyz.sh/
Alternatives to this implementation:
https://github.com/barabo/advanced-shell-history
both are fairly featureful and capture additional metadata about the commands run
it is also possible to use similar tools to log your bash history to mysql, or to syslog, which may be preferable for auditing purposes.
I've gradually come up with a way too elaborate system for maintaining and sharing bash histories locally. I run tmux with several long-running bash prompts and not only I want to append each shell's history into a log incrementally but also to share history between the running shells.
I have a function as my prompt command that does:
- dump the current in-memory history into a separate logfile every few minutes timestamped (using HISTTIMEFORMAT)
- clear the local in-memory history and reload in-memory history from unique history lines from all stored log files, using the most recent timestamp on each
Once there are more than N log files, one of the shells does a similar uniquefying compation step for N log files and writes the output into one new log file. It uses 'mv' to do the compation atomically by moving the affected log files away into a temporary directory for compaction.
If other shells were to update their logs during the compaction those additions would just be saved as normal and compacted in the next cycle. There are always duplicate history lines in the logs to keep things fast so there's no chance for a race condition: no command line in the history can get accidentally deleted and any duplicates are just removed during reading.
As a final step I atomically copy the latest compacted history into .bash_history as a backup. The real data lives in my logs anyway but a single .bash_history is easier to backup: it might be a few lines short but it's always mostly up-to-date.
Looking back at this, I reckon the current Bash history implementation surely can't be ideal.
Wow, cool! How does this handle the case of multiple shells writing to the history at the same time? I have yet to find a safe way to preserve all that.
I really like how the search feature shows the frequency of each entry. I've thought before it would be cool to see the most used commands of some of the more experienced folks I work with, though ideally it would be slightly more generic than exact commands - i.e. Different arguments would count for the same command.
Or, you know, put out the "random fires that burn down your history"
I like this. It looks like a much better fleshed out version of a one-off python script I use to search bash history - it even coincidentally has the same name so it'll fit right into the muscle memory :D
https://stackoverflow.com/questions/43019250/made-quick-scri...
HISTFILE=~/bash_history/$(date +%Y-%m) with h() { grep -a $@ ~/bash_history/* }
Work for me... I don't lose bash history.
https://github.com/kaihendry/dotfiles/blob/master/.bashrc#L3...
I love this idea. It's not important for production / env that are managed through tooling, but the "randomish" nature of losing history on dev/stage is one of those, admittedly minor, annoyances that this would solve.
Great idea, thanks for sharing.
I've been using a variant of this: https://debian-administration.org/article/543/Bash_eternal_h... which adds all commands to a file ~/.bash_eternal_history
Plus a script named "ehist" in my path which contains "cat ~/.bash_eternal_history" -- this enables searches with "ehist | grep git"
It also handles the case of multiple shells writing to a history file.
Some sites require the periodic deletion of .bash_history and .history files as a security policy, because they're quite likely to contain passwords and other secrets in them.
I wish there were a tool to share .bash_history across an organization. This would make onboarding so much easier. It would also help to disseminate shell tricks.
I think a lot of the problems linked to bash history could be solved elegantly by the use of a daemon to exchange information between concurrently opened shells.
On a sidenote, how do I tell bash to immediately commit to history? I often close iterm tabs with cmd-w which seems to make my bash forget to write history.
How can we store history of many users [with screen sessions] on another server - as a simple history keeping and monitoring thing? I looked into auditd but did not like the logging format (maybe there is just a nice web front-end missing that interprets the details) - a simple history would be enough.
Next todo was to look if we could send the history to some syslog server - do you have any experiences with a similar solution?
I use my shell history to pickup past command invocations, but at some point, you have to clean things up and create a script. The script could be for repetitive tasks or help tame complicated command line syntax. The nmap, curl and groff utilities are a few of my favorite examples of commands that have too many options.
my bash history gets deleted whenever I inadvertently type my password and hit enter at the wrong prompt. Type sudo 30 time a day, its gonna happen. Yes I know my history has permissions protection, but still. It is plain text. I don't want to have to look for all the places it get copied too with these solutions.
As a pen tester who frequently finds passwords and other sensitive data in shell history files[1], I fully support this effort to make my job even easier :).
[1] Either inline in mysql-type commands, or when users accidentally paste/type their password in when the system isn't expecting it.
If you touch ZSH (oh my zsh, if that makes a difference) once you will never ever want to use bash again.
I use git/gitlab in a private repo to keep track of my zsh profile and history. Stupid like a fox!
What are the random fires? please provide an example, i like to control my HISTFILE
edit: FIRE == OSX specific
"In its nascent form, a script backs up your .bash_history into a SQLite database that sits in your home directory as well."
I only save about 40 lines of shell history. If I find myself repeating something I make a script or alias.
Root account never saves history.
I think this is nice. I use tmux every day and this will help me to keep my bash history in my multiple tabs.
ctrl-r is great, but i'd like to also delete unwanted results and favourite some and label them.
Are there any bash history systems which also store the directory the command was issued in?
didn't even know that's the case, is zsh affected by this mac os bug?
My hand made script doing the same thing is also called "hist".
TIL about figlet and cowsay.
Thanks HN!
fish
im on linux but i limit it to 50(user) and auto remove duplicates(system wide). albiet i have read man pages and wiki's to understand and have got into a bit of bash or sh scripting but the things i mentioned are just options.
For those on zsh I have something similar [1-2]. It hooks to zshaddhistory and stores the command, running time, CWD, hostname and exit status in a sqlite database, and provides a simple query command.
With a git merge driver [3] the history database can be kept in source control and shared between hosts.
Queries look a bit like
The sess column here is a unique (per-host) session number which means it can recreate any transcript with a suitable query; if I ran histdb -s 24 it would produce the whole session containing the top two results above, including directory history.[1] https://github.com/larkery/zsh/blob/master/sqlite-history.zs... [2] https://github.com/larkery/zsh/blob/master/self-insert-overr... [3] https://github.com/larkery/zsh/blob/master/histdb-merge.zsh