在我的相关帖子很多年前,我找到了一个解决方案,如何注释掉 bash 历史记录中保存的“危险”命令,这样我就不会意外执行它们。
在 中实施相同的最佳解决方案是什么zsh
?
是否zsh
提供了一些我可以用于此目的的功能?我认为,zsh
beieng 更灵活,这应该更容易zsh
。
作为参考,这是我一直在使用的bash
(基于 Stéphane Chazelas 接受的答案):
fixhist() {
local cmd time histnum
cmd=$(HISTTIMEFORMAT='<%s>' history 1)
histnum=$((${cmd%%[<*]*}))
time=${cmd%%>*}
time=${time#*<}
cmd=${cmd#*>}
case $cmd in
(cp\ *|mv\ *|rm\ *|cat\ *\>*|pv\ *|dd\ *)
history -d "$histnum" # delete
history -a
[ -f "$HISTFILE" ] && printf '#%s\n' "$time" " $cmd" >> "$HISTFILE";;
(*)
history -a
esac
history -c
history -r
}
2022 年 9 月 5 日更新:
公认的解决方案有效,但有意想不到的副作用。它搞乱了insert-last-word
键绑定。这里简短的说明:
我使用我的“危险”命令之一:
rm zz
它已被添加到历史记录中并带有注释(根据需要):
history
...
# rm zz
让我们向历史记录添加另一个命令
echo foo
Alt现在,当我想用 +循环历史记录时.,我得到以下结果:
echo <Alt> + .
foo
history
# rm zz
我没有被提供,而是zz
被提供了整个评论命令# rm zz
。
我怎样才能解决这个问题 ?
答案1
当然,使用zshaddhistory
钩子函数并禁用常规历史记录处理。
function zshaddhistory() {
# defang naughty commands; the entire history entry is in $1
if [[ $1 =~ "cp\ *|mv\ *|rm\ *|cat\ *\>|pv\ *|dd\ *" ]]; then
1="# $1"
fi
# write to usual history location
print -sr -- ${1%%$'\n'}
# do not save the history line. if you have a chain of zshaddhistory
# hook functions, this may be more complicated to manage, depending
# on what those other hooks do (man zshall | less -p zshaddhistory)
return 1
}
在 zsh 5.0.8 上进行了测试
% exec zsh
% echo good
good
% echo bad; rm /etc
bad
rm: /etc: Operation not permitted
% history | tail -4
299 exec zsh
300 echo good
301 # echo bad; rm /etc
302 history | tail -4
%
extendedhistory
这似乎也适用于选项集。
答案2
以下功能基于 thrig 的功能并进行了修复histignorespace
:
function zshaddhistory() {
if [[ $1 =~ "^ " ]]; then
return 0
elif [[ $1 =~ "cp\ *|mv\ *|rm\ *|cat\ *\>|pv\ *|dd\ *" ]]; then
1="# $1"
fi
# write to usual history location
print -sr -- ${1%%$'\n'}
# do not save the history line. if you have a chain of zshaddhistory
# hook functions, this may be more complicated to manage, depending
# on what those other hooks do (man zshall | less -p zshaddhistory)
return 1
}