抬头仰望星空,是否能发现自己的渺小。

伪斜杠青年

人们总是混淆了欲望和理想

使 Zsh / Bash History 不记录错误(command not found)命令

背景

这一直是一个不痛不痒的问题,手抖敲错命令很常见,长年累月下来,在使用 zsh_autosuggestions 时就会很被动。

原理

在任意一条命令执行完毕后,读取其返回值,判断命令是否有效(exit status 127 表示 command not found),若无效则将其从历史记录中删除。

其中, zsh 不会在每个交互提示信息出现之前执行 ${PROMPT_COMMAND} 中的指令,而是提供 precmd 函数来实现类似的功能;

另外,zsh 内建的 history 命令与 bash 有一定差异,比如它不支持通过 history -d 删除单条命令历史记录,而需要使用 fc 命令手动操作历史记录文件(参考 stackexchange)。

用法用量

理论支持 bashzsh,经验证 zsh 可用,bash 未曾尝试。

zsh 为例,新建文件:.his_ignore_error.env 放到与.zshrc 同级位置。

[ ${BASH_VERSION} ] && PROMPT_COMMAND="mypromptcommand"
[ ${ZSH_VERSION} ] && precmd() { mypromptcommand; }
function mypromptcommand {
local exit_status=$?
if [ ${ZSH_VERSION} ]; then
local number=$(history -1 | awk '{print $1}')
elif [ ${BASH_VERSION} ]; then
local number=$(history 1 | awk '{print $1}')
fi
# echo $number
if [ -n "$number" ]; then
# If the exit status was 127, the command was not found. Let's remove it from history
if [ $exit_status -eq 127 ] && ([ -z $HISTLASTENTRY ] || [ $HISTLASTENTRY -lt $number ]); then
local RED='\033[0;31m'
local NC='\033[0m'
if [ ${ZSH_VERSION} ]; then
local HISTORY_IGNORE="${(b)$(fc -ln $number $number)}"
fc -W
fc -p $HISTFILE $HISTSIZE $SAVEHIST
elif [ ${BASH_VERSION} ]; then
local HISTORY_IGNORE=$(history 1 | awk '{print $2}')
history -d $number
fi
# echo -e "${RED}Deleted '$HISTORY_IGNORE' from history.${NC}"
else
HISTLASTENTRY=$number
fi
fi
}

.zshrc 末尾追加:

. "./.his_ignore_error.env"

最后:

source ~/.zshrc

PS:echo -e 取消注释可开启删除提示。

另外,如果不希望记录连续输入的相同指令可在 .zshrc 末尾追加:

setopt HIST_IGNORE_DUPS

其他

之前找 GPT ,GPT 说配置 HIST_IGNORE_ERRORS,经过尝试与查看 Zsh 文档,属于无中生有,告知无效后才提到 precmd()函数,经过多次尝试,未能给出合理解决方案,能帮但不多。

本文内容搬于:

从 shell history 中排除无效命令

Avoiding invalid commands in Bash history | boltblog


本站由以下主机服务商提供服务支持:

0条评论

发表评论