![如何强制 Bash 单词引用别名、函数、文件等?](https://linux22.com/image/28116/%E5%A6%82%E4%BD%95%E5%BC%BA%E5%88%B6%20Bash%20%E5%8D%95%E8%AF%8D%E5%BC%95%E7%94%A8%E5%88%AB%E5%90%8D%E3%80%81%E5%87%BD%E6%95%B0%E3%80%81%E6%96%87%E4%BB%B6%E7%AD%89%EF%BC%9F.png)
当尝试向相关的内容添加更多细节时问题,我意识到我不知道如何指定要执行哪一种可用的 Bash 单词类型。根据help type
词型有五种:
- 别名
- 关键词
- 功能
- 内置
- 文件
一个单词可能有多种类型(true
这只是一个例子;更常见的被覆盖的单词是cd
):
$ type -a true
true is a shell builtin
true is /bin/true
如何强制执行特定同义词?到目前为止,按优先顺序排列:
别名:这是一种特殊情况,因为它优先于所有其他同义词。仅当未定义别名且命令失败时,强制执行此操作才有用。
$
关键词:
$
功能:
$
内置:
$ builtin true
文件:
$ command true $ $(which true) $ /bin/true
引用单词不包括别名和关键字。那是,
$ 'true'
将仅运行函数、内置函数或文件。
答案1
你问的其实没有多大意义。
关键词意味着它是 shell 语法一部分的单词。这些是通过标记化来识别的。引用它们就足以让 shell 停止识别。
不过,在大多数 shell 中都可以为关键字设置别名。因此,别名优先于关键字(实际上它们会提前扩展,之后会有更多的标记化,您可以拥有更多别名、关键字)...
别名(除 zsh 定义的别名外,alias -g
仅在命令位置扩展),因此通常不在builtin the-alias
.
函数优先于内置命令,内置命令优先于外部命令(然后$PATH
决定使用哪一个)。
您可以使用以下命令强制内置:
builtin the-cmd and its args
(尽管应该注意它不是标准命令)。
您可以通过引用别名来禁用别名(尽管在某些 shell 中引用的版本也可以被用作别名)。
因此,例如(这里是 zsh 语法),在:
'while'() echo function while
alias 'while=echo alias while'
写入while true
实际上会输出alias while true
,并且无法使用该while
关键字,因为引用它会禁用别名和关键字。
while
例如,您可以使用以下命令调用该函数:
'whi'le whatever
如果有一个while
内置函数(但当然它们不会在那些有while
关键字的 shell 中),你可以这样写:
builtin while whatever
要调用该while
命令,您可以编写:
env while whatever
或zsh
(当不在sh
仿真中时):
command while whatever
(在其他 shell 中,command
仅阻止函数,而不阻止内置函数)
或者
/full/path/to/while whatever
当然,没有什么可以阻止你做更愚蠢的事情,比如:
alias 'while=while "w"hile; do'
"while"() { while "whi"le; done; }
至少在 zsh 中这是有效的(但很愚蠢)。
答案2
对我来说一个非常有用的习语是:
FALSE=1; TRUE=0
DEVEL_FLAG=$FALSE
...
in_development() { return $DEVEL_FLAG ; }
cd()
{
if in_development ; then # -D argument to script toggles development flag
echo "Would run cd $*"
else
builtin cd "$@"
fi
}
现在,如果我运行指定 -D 的脚本,则会激活开发模式,并且 cd (或任何其他包装命令)会回显调试信息
这对于运行 ssh 的脚本特别有用。当然我可以切换 set -x,但这对我来说更有用和可读。