最近我尝试覆盖三个常见命令:
第一个(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() {
表示法避免。
如果我使用的是交互式外壳,则可以使用alias解决该问题;重现步骤:
_select() { echo using custom select;}
alias select='_select'
select
BUT如果使用文件,此解决方案将不起作用。
让我们尝试以下内容:
#!/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
,则当我尝试调用别名时会出现错误。
对我来说,这是别名是内置函数之后的“第二选择”。
我做错什么了吗,或者这是一个实际的“错误”?
显然,一种解决方法是将函数重命名为其他名称。
从bash
部分的ALIASES
手册页:
除非shell不交互,否则别名不会展开,除非设置了
expand_aliases
shell选项使用小商店(请参阅下面shopt
下的SHELL BUILTIN COMMANDS
的说明)。
都添加
shopt -s expand_aliases
在select
之前或将-i
添加到您的shebang中>>
#!/bin/bash -i
用于交互式外壳。