【发布时间】:2020-03-08 17:42:17
【问题描述】:
最近我尝试覆盖三个常用命令:
- 睡觉
- 等一下
- 选择
第一个(sleep)通常是一个外部 bin(在我的 Debian 10 中为/bin/sleep)。
第二个(wait)是内置的(你可以用command -v wait检查它)。
第三个(select)也是内置的。
我会写一些例子来复现哪些有效,哪些无效,请耐心等待。
覆盖sleep 和wait 没有问题,我只是在代码的某处添加了以下内容:
sleep() {
echo using custom sleep
}
wait() {
echo using custom wait
}
当我尝试覆盖 select 时,情况发生了变化。
特别是,如果我尝试像上面那样创建一个简单的函数,我会收到错误,因为解析器 (?) 认为我正在尝试使用该命令而不是创建一个新函数。
您可以通过以下方式重现错误:
#!/bin/bash
select() {
echo using custom select
}
使用 function select() { 符号可以避免这种情况。
如果我使用的是交互式 shell,我可以使用 别名 解决问题;重现步骤:
_select() { echo using custom select;}
alias select='_select'
select
但是如果我使用文件,此解决方案将不起作用。
让我们尝试一下:
#!/bin/bash
# this is the actual script
. lib.sh
select
...和:
#!/bin/bash
# this is where I declare the function select
_select() {
echo using custom select
}
alias select='_select'
如果我运行script,而后者又是lib.sh,当我尝试调用我的别名时会出错。
对我来说,这是第一次,别名是内置函数之后的“第二选择”。
是我做错了什么还是这是一个实际的“错误”?
显然,一种解决方法是将函数重命名为其他名称。
【问题讨论】:
-
顺便说一句。
select是关键字,没有内置关键字。 -
@Cyrus 感谢您的这种区别,我搜索了关键字和内置函数之间的差异,它确实解决了我的疑问。特别是,我发现在 bash 解析的早期就扫描了关键字,这就是原因。此外,使用
type select比command -v select确定这一点要好得多。如果您愿意,请给出实际答案,我会将其标记为正确的。
标签: bash function alias keyword undefined-behavior