如何禁用 shell 关键字?

如何禁用 shell 关键字?

使用enable内置命令我们可以禁用 shell 内置命令,例如echo,如下所示:

enable -n echo

但是我们如何禁用像这样的 shell 关键字呢time?如果我们尝试:

enable -n time

我们将得到以下“答案”:

bash: enable: time: not a shell builtin

笔记: 我知道怎么办跑过time那是在/usr/bin,所以我只想知道是否有可能完成我在标题中提出的要求。

答案1

你可以做:

alias time='"time" '

(尾随空格是为了允许在其后进行别名扩展,作为奖励)。

引用关键字(关键字是 shell 语言语法的一部分)会阻止它被解释为关键字,因此这里对其执行正常的命令查找。

它适用于bash, zsh, mksh,但不适用于ksh93,ashyash

请注意,对于非交互式实例(例如在脚本中),与其他 shell 相反,bash您需要在非交互式时默认不扩展别名。shopt -s expand_aliasesbash

答案2

正如您所发现的,您不能禁用带有 的关键字enable -n

但是,您也可以将关键字设为内置关键字enable -f,然后禁用它:

  • 解压当前版本的源代码bash
  • ./configure && make
  • 在 中examples/loadables,您将找到许多示例可加载内置函数,编辑其中之一,例如将sync的所有实例替换为 的那个。synctime
  • 跑进。makeexamples/loadables
  • bash,运行enable -f ./sync time
  • enable -n time现在可以了。并help显示:(*time除了time [-p] pipeline

(并不是说它对任何人都有用)。

答案3

如果您可以在 shell 解析器找不到它的情况下调用它,而不是禁用该关键字指挥位置- 或简单命令中的第一个单词 - 您应该能够毫无问题地运行它。 POSIX 指定的命令command就是为了做到这一点而设计的。例如,您可以调用time如下命令:

command time

据我所知,这在任何 shell 中都有效。但奇怪的是,许多人似乎以不同的方式处理它。这是一个演示:

echo 'echo "$0"' >./time
chmod +x ./time
for sh in dash ksh zsh bash yash 'busybox ash' posh mksh
do  command -p $sh -c '
    PATH=.:$PATH
    printf "\n%s\n" "$0"
    time
    command time' "$sh"
done 

输出

dash
./time
./time

ksh
user    0m0.00s
sys     0m0.00s
time

zsh
shell  0.00s user 0.00s system 71% cpu 0.005 total
children  0.00s user 0.00s system 0% cpu 0.005 total
time

bash

real    0m0.000s
user    0m0.000s
sys     0m0.000s
./time

yash
./time
./time

busybox ash
./time
./time

posh
./time
./time

mksh
    0m0.00s user     0m0.00s system
./time

答案4

您无法禁用它,但可以使用函数隐藏它。使用风险自负。

shell_builtin() {
    :  ## Do nothing.
}

要重新启用它,只需取消设置即可:

unset shell_builtin

相关内容