boltblog

Avoiding invalid commands in Bash history

Posted on June 24, 2010

To avoid having stuff like "ls" in my bash history, I added "ls" to the "HISTIGNORE" environment variable.
However, on late nights, the result of this, and my left and right hand becoming out of sync with each other when I'm tired, is that the entry "sl", which really doesn't do anything, started showing up in my history instead.

Now, invalid commands in bash result in two things. A message saying "command not found" and exit status 127.
The latter is interesting. We can use that to avoid having the invalid entries showing up in the history.

If you don't already have a bash PROMPT_COMMAND set, add this to .bashrc:

PROMPT_COMMAND="mypromptcommand"
function mypromptcommand {
}

That function will now be run every time your prompt is about to appear. Within it, we put this:

local exit_status=$?
# If the exit status was 127, the command was not found. Let's remove it from history
local number=$(history | tail -n 1 | awk '{print $1}')
if [ -n "$number" ]; then
    if [ $exit_status -eq 127 ] && ([ -z $HISTLASTENTRY ] || [ $HISTLASTENTRY -lt $number ]); then
        history -d $number
    else
        HISTLASTENTRY=$number
    fi
fi

What this does:

  • Gets the exit status of the last command
  • Gets the number for the latest entry in your history, if there is one
  • Checks if that entry was set to anything
  • If it was, we check if the exit status and see if it's 127. We also require the HISTLASTENTRY variable to be either unset or less than the number of the latest history entry. This means the command in question was either added to the history, increasing the number of entries already there, or it was the first command ever (empty history)
  • If the above is true, we delete the last history entry
  • Otherwise, we set the last history entry to the amount of entries we found, so we can check if it is increased next time.
Filed under: Howto's, Linux No Comments