![我可以在终端中忽略前导感叹号吗? (由于 ipython,我凭本能输入它们)](https://linux22.com/image/165173/%E6%88%91%E5%8F%AF%E4%BB%A5%E5%9C%A8%E7%BB%88%E7%AB%AF%E4%B8%AD%E5%BF%BD%E7%95%A5%E5%89%8D%E5%AF%BC%E6%84%9F%E5%8F%B9%E5%8F%B7%E5%90%97%EF%BC%9F%20%EF%BC%88%E7%94%B1%E4%BA%8E%20ipython%EF%BC%8C%E6%88%91%E5%87%AD%E6%9C%AC%E8%83%BD%E8%BE%93%E5%85%A5%E5%AE%83%E4%BB%AC%EF%BC%89.png)
因为我一生的大部分时间都在 IPython shell 中度过,所以我有一个在终端命令前面加上感叹号的坏习惯。通常,这只会导致错误,但有时,它会导致不好的事情发生。我可以有效地禁用!
终端中的功能吗?这是否会有干扰任何脚本的风险?
答案1
在交互式 shell 中,默认情况下,!
用于历史扩展:shell 将查找与以下文本匹配的命令!
,并执行该命令。如中所示这个答案到bash 中不能使用感叹号 (!)?shell 允许禁用历史扩展:
- 重击:
set +H
- 兹什:
set -K
如果您不想使用由感叹号驱动的历史扩展,您可以将它们添加到 shell 的启动脚本中。
这些不会!
被忽略,但它们会避免运行历史记录中的命令。!command
会抱怨!command
不存在。
Shell 脚本不受这些设置的影响,它们使用非交互式配置获得自己的 shell(默认情况下不包括历史扩展)。
答案2
如果你从不使用!从终端,您可以将其分配给您也从未使用过的函数,例如(在我的例子中)werase:
stty werase !
然后每当您输入时! ,它只会删除前一个单词。如果您只在终端命令的开头键入它,那么这根本没有效果。
如果您需要实际的感叹号,您仍然可以通过在其前面加上 CTRL-V(或您的lnext
角色是什么)来引用它/转义它来输入它。
如果您通常不使用该lnext
功能,您可能会发现重新定义lnext
为更方便!
;这将允许您通过输入两次来输入感叹号(第一个引用第二个)。
stty lnext !
关于其工作原理的更详细解释:
功能lnext
是:“不将下一个字符解释为任何特殊字符:只接受该字符作为输入”。如果它是一个 stty 特殊字符,则不应用该特殊功能,而只使用该字符本身。这包括分配给该lnext
函数的字符。
默认lnext
字符是 CTRL-V(助记符:“逐字”,如:逐字输入下一个字符)。在这里,我们将该功能重新分配给角色!
。
lnext
选择它主要是因为在大多数情况下它的效果是“无效果”(例如,当键入的下一个字符是普通字符时)。当您不小心在行!
首键入时,下一个字符几乎总是普通字符,无需特殊操作,因此引用/转义它(将其明确视为普通字符)不会造成任何损害。当我们在 ana
后面写 an时!
,含义从“写一个a
”变为具有相同功能的更具体的含义:“写一个a
,忽略其他任何内容,就做吧!”
如果我们想创建一个实际的!
角色,我们可以使用该lnext
功能来引用它。因此,通过输入,就输入了!!
一个。!
答案3
如果使用zsh
shell,您可以添加到您的~/.zshrc
:
zmodload zsh/zselect
bang() {
zle self-insert
if [[ $CONTEXT = start && $LBUFFER =~ '^!+$' ]]; then
local -a old_region_highlight=($region_highlight)
region_highlight+=("0 $CURSOR fg=red,bg=white,bold,standout")
zle -R 'Will you please stop?!'
zselect -t 100 -r 0 < /dev/tty
region_highlight=($old_region_highlight)
LBUFFER=
fi
}
zle -N bang
bindkey '!' bang
这样,当您!
在编辑缓冲区的开头输入一个或多个时,它会以红色突出显示它们,给您一条消息并删除它们(一秒钟后,或者如果您输入其他任何内容则更快)。