我为命令行写了钩子(Hook):
# Transforms command 'ls?' to 'man ls'
function question_to_man() {
if [[ $2 =~ '^\w+\?$' ]]; then
man ${2[0,-2]}
fi
}
autoload -Uz add-zsh-hook
add-zsh-hook preexec question_to_man
但是当我这样做的时候:
> ls?
从 man
退出后,我得到:
> zsh: no matches found: ls?
如何摆脱有关错误命令的消息?
最佳答案
?
对 zsh 是特殊的,是单个字符的通配符。这意味着如果您键入 ls?
zsh 会尝试在当前目录中查找匹配的文件名(任何以“ls”开头的三个字母的名称)。
有两种方法可以解决这个问题:
你可以制作“?”通过引号表示“不特殊”:
ls\?
、'ls?'
或"ls?"
。你让 zsh 更好地处理不匹配的情况:
如果找不到匹配项,默认行为是打印错误。这可以通过禁用
NOMATCH
选项来改变(也不能设置NULL_GLOB
):setopt NO_NOMATCH setopt NO_NULL_GLOB
如果没有匹配的文件,这将保持单词不变。
警告:在(可能不太可能)存在具有匹配名称的文件的情况下,zsh 将尝试执行具有第一个匹配名称的命令文件。也就是说,如果有一个名为“lsx”的文件,那么
ls?
将被替换为lsx
并且 zsh 将尝试运行它。这可能会也可能不会失败,但很可能不会达到预期的效果。
这两种方法各有利弊。 1. 可能不完全是您要找的东西,并且 2. 并非每次都有效,并且会改变您的 shell 行为。
另外(正如@chepner 在他的评论中指出的那样)preexec
额外运行而不是命令。这意味着您可以获得 ls
的帮助,但 zsh 仍会尝试运行 ls?
甚至 lsx
(或其他匹配名称)。
为避免这种情况,我建议定义一个 command_not_found_handler
函数而不是 preexec
。来自zsh manual :
If no external command is found but a function
command_not_found_handler
exists the shell executes this function with all command line arguments. The function should return status zero if it successfully handled the command, or non-zero status if it failed. In the latter case the standard handling is applied: ‘command not found’ is printed to standard error and the shell exits with status 127. Note that the handler is executed in a subshell forked to execute an external command, hence changes to directories, shell parameters, etc. have no effect on the main shell.
所以这应该可以解决问题:
command_not_found_handler () {
if [[ $1 =~ '\?$' ]]; then
man ${1%\?}
return 0
else
return 1
fi
}
如果您有很多匹配的文件名,但很少输入错误的命令(“找不到命令”错误的常见原因),您可能需要考虑改用它:
command_not_found_handler () {
man ${1%?}
}
这不会检查“?”最后,只是删除最后一个字符(注意 ${1%?}
中缺少的“\”)并尝试在其余部分运行 man
。因此,即使文件名匹配,man
也会运行,除非确实存在与匹配文件同名的命令。
注意:这会干扰使用 command_not_found_handler
的其他工具,例如来自 Ubuntu 的 command-not-found
工具(如果为 zsh 启用) ).
综上所述,zsh 有一个名为 run-help
的小部件,它可以绑定(bind)到一个键(在 Emacs 模式下,它默认绑定(bind)到 Alt+H) 然后为当前命令运行 man
。
使用 run-help
的主要优点是:
- 您可以在键入较长命令时随时调用它,只要命令名称完整即可。
- 离开联机帮助页后,命令仍未更改,因此您可以继续在上面书写。
您甚至可以将其绑定(bind)到 Alt+? 以使其更相似:bindkey '^[?'运行帮助
关于linux - 如何防止在 ZSH 中执行命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30028730/