使bash使用外部`time`命令而不是内置的shell


27

如何让bash默认使用时间二进制(/ usr / bin / time)而不是shell关键字?

which time收益/usr/bin/time
type time回报time is a shell keyword
运行time显然是执行外壳关键字:

$ time

real    0m0.000s
user    0m0.000s
sys     0m0.000s
$ /usr/bin/time
Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]
   [--portability] [--format=format] [--output=file] [--version]
   [--quiet] [--help] command [arg...]

enable -n time 退货 bash: enable: time: not a shell builtin

Answers:


30

您可以使用command内置的Shell绕过正常的查找过程,而将给定的命令作为外部命令运行,而不考虑其他任何可能性(内置的Shell,别名等)。这通常在需要跨系统移植的脚本中完成,尽管可能更常用速记\(如\rm而不是command rmrm,因为尤其是后者可能是不知名的东西的别名rm -i)。

$ time

real    0m0.000s
user    0m0.000s
sys 0m0.000s
$ command time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
       [--portability] [--format=format] [--output=file] [--version]
       [--quiet] [--help] command [arg...]
$ 

可以将其与别名一起使用,如下所示:

$ alias time='command time'
$ time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
       [--portability] [--format=format] [--output=file] [--version]
       [--quiet] [--help] command [arg...]
$ 

相对于例如的优点alias time=/usr/bin/time是,您无需指定time二进制文件的完整路径,而可以使用常规的路径搜索机制。

alias命令本身可以进入〜/ .bashrc或/etc/bash.bashrc(后者对于系统上的所有用户都是全局的)。

在相反的情况下(如果定义了别名,则强制使用内置的shell),您可以使用,如builtin time,它将再次覆盖通常的搜索过程并运行内置的命名shell。bash手册页提到,通常使用此功能是为了为cd名为的功能提供自定义功能,而该功能cd又使用内置功能cd来完成实际工作。


您还可以使用命令查询特定命令的来源type -a <cmd>
slm

12
command不绕过内建函数(除非zsh不模拟其他外壳)。它绕过了功能,这就是它存在的主要原因。它的第二个作用是去除特殊特殊内建命令。它仅绕开别名和关键字,因为它们仅在第一位置扩展(zsh例如,它不绕过全局别名)。没有time内置的bash。time是关键字,因此您可以做例如time { foo; bar; }
斯特凡Chazelas

1
@StephaneChazelas可以随时将其编辑为答案以提供更准确的描述。command如示例所示,它在这种特定情况下可以工作,但显然正确的答案比半正确的答案更好。
CVn 2013年

1
您的答案的最后一部分是错误的。time不是内置的shell,而是shell关键字。builtin time不起作用。
Teresa e Junior

与命令类似,只是引用它:'time' echo test
mxmlnkn

9

bash中有一个避开关键字的快捷方式,而无需指定路径或使用其他内置函数,例如command:用反斜杠将其转义。

=^_^= izkata@Izein:~$ time

real    0m0.000s
user    0m0.000s
sys     0m0.000s
=^_^= izkata@Izein:~$ \time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
       [--portability] [--format=format] [--output=file] [--version]
       [--quiet] [--help] command [arg...]

就个人而言,我认为这更容易阅读和更安全,因为这是可能的:

=^_^= izkata@Izein:~$ alias command=echo
=^_^= izkata@Izein:~$ command time
time

8
需要注意的是,它使任何形式的报价或任何的令牌time会做:ti\me'time'ti""meti${-##*}me${-+time}...这适用于任何shell关键字。
斯特凡Chazelas

我见过的最好的PS1。
maxywb

1
@maxywb而且,这不仅是装饰性的-如果最后一个命令失败,笑脸就会变成红色(x_x)
Izkata

4

内置的一般解决方案(例如测试)为[1]

  • 使用env(所有壳)

    $ env test
    external test
  • 禁用内置功能(仅bash和zsh):

    $ test 1 = 1 && echo "yes"
    yes
    $ enable -n test        ### for bash. Re-enable with "enable test".
    $ disable test          ### for zsh. Re-enable with "enable test".
    $ test
    external test
  • 使用任何斜杠/来调用命令(所有shell):

    $ test 1 = 1 && echo "yes"
    yes 
    $ ~/bin/test
    external test
  • 进行别名(除非shopt -s expand_aliases使用bash脚本,否则在bash脚本中失败):

    $ alias test='~/bin/test'             ### remove with 'unalias test'.
    $ test
    external test

但是时间不是内在的。

该单词time是“保留单词”,不是命令,也不是内置单词。这样可以实现以下解决方案:

  • 引用这个词。这不适用于内置插件。
    多种形式的报价工作: \time "time" 'time' ti\me ti"me",等等。

    $  time
    
    real    0m0.000s
    user    0m0.000s
    sys     0m0.000s
    
    $ \time
    Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]
           [--portability] [--format=format] [--output=file] [--version]
           [--quiet] [--help] command [arg...]

    这对于绕开别名很有用。即使test是别名,\test也将执行PATHed命令(或内置命令,如果尚未禁用)。

  • 使用内置功能command(不适用于内置功能):

    $ command time
  • 如上,对于内置插件,使用任何斜杠均可/

    $ /usr/bin/time
  • 与上面的内置插件一样,别名在这里也适用:

    $ alias time='command time'
    $ alias time='/usr/bin/time'

[1]假设其中有一个外部可执行文件,其中~/bin/test显示“外部测试”。进一步:让我们假设它在活动路径中~/bin位于前面/bin



2

您可以使用该enable命令禁用某些内置程序。

$ enable -n kill

但是time是一个关键字,因此无法使用。

$ builtin time
bash: builtin: time: not a shell builtin

因此,剩下的就是创建一个别名来覆盖它:

$ alias time=/usr/bin/time

不。time是一个shell关键字,而不是一个内置的shell。我刚要编辑我的问题,说当我看到您回答时,enable -n不起作用。
大卫·霍尔德曼
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.