tell if last command was empty in PROMPT_COMMAND

Check whether the history number was incremented. A cancelled prompt or a prompt where the user just pressed Enter won't increment the history number.

The history number is available in the variable HISTCMD, but this is not available in PROMPT_COMMAND (because what you want there is in fact the history number of the previous command; the command that executes PROMPT_COMMAND itself has no history number). You can get the number from the output of fc.

prompt_command () {
  HISTCMD_previous=$(fc -l -1); HISTCMD_previous=${HISTCMD_previous%%$'[\t ]'*}
  if [[ -z $HISTCMD_before_last ]]; then
    # initial prompt
  elif [[ $HISTCMD_before_last = "$HISTCMD_previous" ]]; then
    # cancelled prompt
  else
    # a command was run
  fi
  HISTCMD_before_last=$HISTCMD_previous
}
PROMPT_COMMAND='prompt_command'

Note that if you've turned on squashing of duplicates in the history (HISTCONTROL=ignoredups or HISTCONTROL=erasedups), this will mistakenly report an empty command after running two identical commands successively.


There is a workaround, but it has some requirements:

You need to set $HISTCONTROL to save ALL commands, also duplicates and spaces. So set:

HISTCONTROL=

Now define a function to call as $PROMPT_COMMAND:

isnewline () {
  # read the last history number
  prompt_command__isnewline__last="$prompt_command__isnewline__curr"
  # get the current history number
  prompt_command__isnewline__curr="$(history 1 | grep -oP '^\ +\K[0-9]+')"
  [ "$prompt_command__isnewline__curr" = "$prompt_command__isnewline__last" ] && \
    echo "User hit return"
}

Now, set the $PROMPT_COMMAND variable:

PROMPT_COMMAND="isnewline"

See the output:

user@host:~$ true
user@host:~$ <return>
User hit return
user@host:~$ <space><return>
user@host:~$ 

Tags:

Bash

Prompt