在我的点文件中一些功能这些命令依赖别名或函数才能运行。出于某种原因,我可以让它们引用我创建的其他函数,但不能引用命令的别名。我该如何解决这个问题?
例子:
function open-dotfiles-commit(){
xopen https://github.com/fatso83/dotfiles/blob/$1;
}
如果我有一个别名xopen
( alias xopen=xdg-open
),open-dotfiles-commit
命令将失败xopen: cannot find command
。另一方面,如果我用名为xopen
( function xopen(){ xdg-open; };
) 的函数替换别名定义,它就可以正常工作!
我甚至尝试shopt -s expand_aliases
在定义别名的同一文件中进行设置 - 但没有成功。别名和函数文件来自我的.bashrc
。
答案1
从bash 手册:
别名是在读取函数定义时展开的,而不是在执行函数时展开,因为函数定义本身就是一个命令。
我敢打赌,您的别名是在定义这些函数之后定义的。稍后尝试定义这些函数。
作为参考,我foo () { ll "$1"; }
使用ll
默认的别名进行了测试.bashrc
,并且运行良好。
可运行示例:
def-before() { do-foo; };
alias do-foo="echo foo u!"
def-after() { do-foo; };
def-before
# prints "do-foo: Could not find command"
def-after
# prints "foo u!"
答案2
Olorin 的回答并没有解决我在 shell 函数中调用别名的问题。我建议避免使用 bash 别名,因为(引自bash 手册以下):For almost every purpose, shell functions are preferred over aliases.
举例来说do-foo
,Olorin 的回答从别名到 shell 函数(同时确保为单行 shell 函数添加分号),do-foo
在另一个 shell 函数中使用它之前定义所述 shell 函数(最初是别名),为了好玩:重新定义do-foo()
然后调用def-after()
:
$ do-foo() { echo 'hello foo'; }
$ def-after() { do-foo; }
$ def-after
hello foo
$ do-foo() { echo 'this is fooey'; }
$ def-after
this is fooey
$
$ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.5 LTS
Release: 20.04
Codename: focal
$
更多细节
我在我的一个 bash 脚本中遇到了和楼主一样的错误Olorin 的回答没有解决它。这显然是因为别名(默认情况下)不会在非交互式环境中扩展,就像我所有的 bash 脚本(包括我上面提到的脚本)一样,如下所示。一旦我将所有别名转换为 shell 函数,一切都会按预期工作。
我现在避免使用 bash 别名,而是尝试专门使用shell 函数。
摘录自bash 手册中有关别名的部分:
Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see The Shopt Builtin).
For almost every purpose, shell functions are preferred over aliases.