I hate the bash 'history' command. It never finds the history items I want. Sometimes I can get what I want with 'history | grep XXX' but often either the history is too long (400+ hits! yay) or too short (no hits. Boo).
I thought to myself, why dont I write a little 'history helper' command that lets me basically 'star' specific history items and make them always turn up in my history, with both a global star list and a cwd specific star list.
Sounds amazing. So I naively tried to read the history by doing this:
system("history > blah")
FILE *fp = fopen("blah", "r")
Oh, that didn't work. Ah, I get it, the system() command runs in it's own context and can't access the bash history. Drats. Ok, so I'll try reading ~/.bash_history
ba baaa~ Nope. That's only got the history up until the last call to either a) history -w, or b) call to exit from the shell.
So, question: How can I programatically access the current bash history in C?
(NB. No, not what's in ~/.bash_history, the current history, the exact output you see when you type 'history' from the prompt; also, why C you ask? why not...but really, because I already have a handy ncurses wrapper I was going to use to let me get fancy auto-completion and sub-selection history searching on normal terminals...)
Edit: Please, if you have something useful to contribute, I'm happy to hear it, but I get a little sick of comments like 'you should read the bash history man pages'.
I have read them. There is nothing that allows me to 'star' a history item and have it always turn up in my history, and nothing that allows me to maintain a per-directory history context. These are things that history does not support. I appreciate this. That's why I want to write a helper function, for my specific purpose. If you have a comment like "maybe you should read the history man pages some more", please just hold it in, and don't respond; it doesn't really address my question. :)
Short answer
You can find the answer into history
source which is bash
builtin.
Long answer
Looks like you just need to read help history
and man bash
a while.
Your history file is constantly rewriting with shell (depending on your settings. by default it is done at the logout/exit moment). You need to hack the shell to add specific rules to do that. However you're pretty far from this level.
just because if you were pretty close to it, you didn't ask how to operate with .bash_history from c
=)
However there is another way to improve your history: increase your history size, restrict duplicate reading and make all your command was getting into history immediately after executing. For that you need put into your .bashrc
following variables:
PROMPT_COMMAND='history -a;history -n'
export HISTCONTROL=ignoredups
export HISTTIMEFORMAT='%F %T '
export HISTSIZE=100500
shopt -s histappend
shopt -s cmdhist
Also you can prevent specific commands recording with
export HISTIGNORE="unwanted_command:unwanted_mask*"
Hope it will help you.
Working-Directory-Specific History
function cd {
builtin cd "$@"
if [ -f .cwdhist ]; then
history -r .cwdhist
fi
}
Starred History Commands
The basic principle is to combine some shell function logic to write and read history around your history helper program.
function histedit {
history -a
historyhelper $HOME/.bash_history $HOME/.histout
history -c
history -r $HOME/.histout
}
The history -a
command appends all recent history to the history file. Then the function invokes your history helper. You can put whatever smarts you want into this program, ensuring that your favorite commands are in the history, and adding them if they aren't, then leaving its output in .histout
(or whatever). Then the function continues, clears, and reloads history. Maybe it should avoid clearing history. Or maybe the function should abort if historyhelper returns a nonzero exit status. All kinds of stuff you can do here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With