zsh 历史:注释掉危险命令:`#`

Mar*_*ter 5 command-history zsh

在我多年前的相关帖子中,我找到了如何注释掉 bash 历史记录中保存的“危险”命令的解决方案,这样我就不会意外执行它们。

在 中实现相同的最佳解决方案是zsh什么?

是否zsh提供了一些我可以用于此目的的功能?我认为,zshbeieng 更灵活,这在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
}
Run Code Online (Sandbox Code Playgroud)

更新:

虽然公认的解决方案有效,但它有不希望的副作用。特别是,zshrc现在将忽略指定的以下历史记录选项

setopt histignorespace
setopt histreduceblanks
Run Code Online (Sandbox Code Playgroud)

我怎样才能让它们再次工作?

thr*_*rig 5

当然,使用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
}
Run Code Online (Sandbox Code Playgroud)

在 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
%   
Run Code Online (Sandbox Code Playgroud)

extendedhistory这似乎也适用于选项集。