我可以在终端中忽略前导感叹号吗? (由于 ipython,我凭本能输入它们)

我可以在终端中忽略前导感叹号吗? (由于 ipython,我凭本能输入它们)

因为我一生的大部分时间都在 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

如果使用zshshell,您可以添加到您的~/.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

这样,当您!在编辑缓冲区的开头输入一个或多个时,它会以红色突出显示它们,给您一条消息并删除它们(一秒钟后,或者如果您输入其他任何内容则更快)。

相关内容