Thursday, January 1, 2015

Fixing Bash History - Impl. Zsh/preexec

Bash history is not shared automatically among different terminal sessions, so what you type in a respective terminal window is in the history for that respective terminal session. It is not normally viewable from other sessions.

Furthermore, Bash history does not provide an easy way to implement the functionality of preexec from ZSH that will execute a function hook *prior* to the command entered at the command prompt.

What Bash has is PROMPT_COMMAND, this will execute *after* the command at the prompt is executed.

So we can add a function to share history among sessions - w/entries in ~/.bashrc file like this:
function my_history() { 
 history -a; 
 history -c; 
 history -r; 
} 
export PROMPT_COMMAND="my_history; ${PROMPT_COMMAND}";
alias h="history -a; history -c; history -r; history" 
and type h from any session to see any commands that have been entered on any terminal after they have returned from executing.

But what if you type in a long running command and then something #(*$& (bad) happens.

Upon rebooting wouldn't it be useful to be able to quickly look at the command history to see what commands were executing at the time of the problem?

If Bash had a preexec like Zsh then it would be easy to simply add our my_history function call to it and the history would be updated BEFORE the command is executed.

Bash does not have this but Bash can emulate the functionality by using trap your_cmd DEBUG, to hook the PROMPT_COMMAND call, the modified .bashrc:
function my_history() { 
 history -a; 
 history -c; 
 history -r; 
} 
  ### ZSH Pre-exec style functionality hack using DEBUG
set -o functrace > /dev/null 2>&1
shopt -s extdebug > /dev/null 2>&1
export PROMPT_COMMAND="my_history; ${PROMPT_COMMAND}";
trap 'my_history' DEBUG;
alias h="history -a; history -c; history -r; history" 

Now our history commands are updated PRIOR to executing and if anything goes wrong we will be able to simply check the history to see what commands were run even if they fail.

This idea is based on an more elaborate implementation that I found here: http://superuser.com/a/175802/365691 that has a link to the code: preexec.bash.txt, the original author is Glyph Lefkowitz according to the posting on superuser.com.

No comments:

Post a Comment