Answers:
检查历史记录号是否增加。取消的提示或用户刚刚按下的提示Enter不会增加历史记录编号。
历史记录号在变量中可用HISTCMD
,但是在中不可用PROMPT_COMMAND
(因为您想要的实际上是上一个命令的历史记录号;执行PROMPT_COMMAND
本身的命令没有历史记录号)。您可以从的输出中获取数字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'
请注意,如果您已打开历史记录(HISTCONTROL=ignoredups
或HISTCONTROL=erasedups
)中的重复数据压缩,那么在连续运行两个相同的命令后,这将错误地报告一个空命令。
${HISTCMD_previous%%$'[\t ]'*}
位丢失了,$'…'
并在`,
t`或空格之后而不是在制表符或空格之后被截断,但是bash打印了一个制表符。
有一种解决方法,但是有一些要求:
您需要设置$HISTCONTROL
为保存所有命令,以及重复和空格。如此设置:
HISTCONTROL=
现在定义一个函数调用为$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"
}
现在,设置$PROMPT_COMMAND
变量:
PROMPT_COMMAND="isnewline"
查看输出:
user@host:~$ true
user@host:~$ <return>
User hit return
user@host:~$ <space><return>
user@host:~$
last
从一次调用isnewline
到下一次调用保留该变量(只能选择一个不太通用的名称,prompt_command__isnewline__last
以避免冲突)。
HISTCONTROL="" function last_was_blank { local last_command="$(history 1)" if [[ "$last_was_blank_PREVIOUS_LINE" = "$last_command" ]] ; then echo "true" else echo "false" fi export last_was_blank_PREVIOUS_LINE="$last_command" } PROMPT_COMMAND=last_was_blank
我不知道的方式做到这一点,本身。但是您可以通过使用获得相同的效果
捕获some_command_or_function调试
这将导致some_command_or_function
被称为运行命令的任何时间。棘手的事情是,如果您刚刚命中,它将不会被调用Enter-除非您定义了PROMPT_COMMAND,在这种情况下,命中会Enter调用PROMPT_COMMAND,从而触发陷阱。
达到所需结果的最简单方法可能是定义调试陷阱函数,而不是使用PROMPT_COMMAND。但是我不能说,因为我不知道你想要什么结果。如果您想在单击时发生某些事情Enter,而在键入命令时又发生其他事情,那么(AFAIK)您需要使用调试陷阱和PROMPT_COMMAND。见这个答案和 这一个 的方法,使这两个机制一起玩很好。