如何在命令行上强制解释为关键字而不是别名?



我有

alias time='/usr/bin/time -v'

在我的 bash 环境中配置。

但是,我有时需要访问某些单行的关键字时间,例如

(expensive-command1 & expensive-command2 & time wait); something-that-requires-prev-commands-to-be-complete

wait显然应该等待expensive-command1expensive-command2完成,并且关键字 time 能够测量所花费的时间。

但是,当我的别名时间指向实际二进制文件时,我会收到以下错误:

/usr/bin/time: cannot run wait: No such file or directory

如何强制keyword上面指挥time的解释?我知道如果我在运行unalias time之前运行它可以工作,但是我的别名就消失了。

我也知道,如果我想从关键字转到实际的二进制,我可以使用语法(cmd1 & cmd2 & command time wait)。如果我需要内置命令,我可以使用语法(cmd1 & cmd2 & builtin time wait).但是,这里需要time不是命令也不是内置的。这是一个keyword,但我无法弄清楚如何让上面的一行话被解释为这样。

在bashrc 中定义别名time的行之前定义如下函数。

_time() { time "$@"; }

然后,您可以在需要关键字时使用_timetime.

$ _time() { time "$@"; }
$ alias time='echo foo'
$ time ls
foo ls
$ _time ls
.bash_history .bashrc
real    0m0.024s
user    0m0.010s
sys     0m0.000s

该手册解释了为什么这样做,如下所示。

别名在读取函数定义时展开,

而不是在执行函数时展开,因为函数定义本身就是命令。


在你无权更改 bashrc 的环境中,你可以执行以下操作:

$ shopt -u expand_aliases
$ _time() { time "$@"; }
$ shopt -s expand_aliases

并获得相同的功能。

从 Bash 版本 4.4 开始,没有很好的方法可以强制解释为关键字而不是别名。有关解决方法,请参阅 oguz ismail 的回答。简而言之,所有解决方法都会为原始关键字行为创建备用名称,然后您必须始终使用备用关键字而不是正确的关键字。

目前,似乎最好的方法是将所有bash关键字视为保留字,并且永远不要定义任何具有相同名称的别名。这是我个人使用的解决方案。

最新更新