Jon*_*fer 9 shell posix quoting time-utility
虽然讨论过之间的差异/usr/bin/time,并内置在外壳(bash和zsh中)time,有人提到可以使用\time作为简写来获得/usr/bin/time。
起初,这似乎是一个很好的无辜捷径,但随后出现了一些问题:
t\ime有效?\cd更改目录,即使/usr/bin/cd¹ 没有?所以很明显,\foo不等价于$(which foo)。现在的问题是:
\foo在 bash 和 zsh 中观察到的行为是否以任何方式被 shell 的 POSIX 定义所涵盖,如果是,为什么它的行为如此?
脚注 1:/usr/bin/cd是,在我的系统上,
#!/bin/sh
builtin cd "$@"
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 14
t\imeor \cd(或"tim"eor'cd'或${-##*}timeor${-+time}以及您能想到的所有其他引用和扩展组合最终会解析为timeor cd),是:另一种写法cd和time.
但是,这最终会解决cd或time稍后解决shell 语法解析和解释。特别是,这种情况发生在 shell 关键字识别和别名替换发生很久之后。
因此,当 shell 在其语言中寻找关键字时,它不会识别ti\me为timeshell 关键字。所以一个:
ti\me echo test
Run Code Online (Sandbox Code Playgroud)
将被 shell 识别为一个简单的命令,而不是time后跟一个简单命令的关键字。
然后ti\me将处理引用(这里反斜杠引用m不需要引用的字符,引用字符被删除,你得到time)并且一个time 命令将像任何其他命令一样被查找(在内置命令列表中) , 中的函数和可执行文件$PATH。很可能会在/bin/time这里)
对于cd,cdshell 语言中没有关键字,只有一个cd内置命令(优先于您的/usr/bin/cd)。但是,如果您确实为cd(like alias cd=pushd)定义了别名,则再次相同。由于别名替换很早就完成了,在删除引号之前,如果您有一个别名 forcd而不是一个 for \cd(请注意,没有多少 shell 允许别名中带有反斜杠),然后通过编写:
\cd dir
Run Code Online (Sandbox Code Playgroud)
你确保你的cd别名没有被替换。
简而言之,引用命令名称或其任何部分可防止其被视为 shell 关键字(诸如while, for, if, {... 之类time的关键字仅在某些shell 中是关键字),并绕过您可能拥有的别名.
但是,它不会强制该命令解析为 中的可执行文件$PATH,该命令仍然首先在函数(您可以通过执行来解决command time cmd...)和内置函数(您可以通过执行来解决env time cmd...,尽管我不知道)中搜索具有内置time命令的外壳)。
请注意,在某些 shell 中,引用也会影响typeset/ declare/ export/ local... 系列的特殊内置函数的行为。请参阅局部变量赋值是否需要引号?详情。