来自 bash 手册
有关别名的定义和使用的规则有些令人困惑。在执行该行上的任何命令之前,Bash 总是至少读取一整行输入。别名在读取命令时展开,而不是在执行命令时展开。因此,与另一个命令出现在同一行的别名定义在读取下一行输入之前不会生效。该行上别名定义后面的命令不受新别名的影响。执行函数时,此行为也是一个问题。 别名在读取函数定义时展开,而不是在执行函数时展开,因为函数定义本身就是一个复合命令。作为结果, 函数中定义的别名只有在执行该函数后才可用。为了安全起见,请始终将别名定义放在单独的行上,并且不要在复合命令中使用别名。
“别名在读取函数定义时展开,而不是在执行函数时展开”和“函数中定义的别名只有在该函数执行后才可用”这两个句子似乎是相互矛盾的。
你能解释一下它们分别代表什么意思吗?
答案1
别名在读取函数定义时展开,而不是在执行函数时展开……
$ echo “敏捷的棕色狐狸跳过了懒狗。” > 我的文件 $ 别名 myalias=cat $ myfunc() { > myalias myfile > } $ myfunc 敏捷的棕色狐狸跳过了懒狗。 $ 别名 myalias="ls -l" $ myalias myfile -rw-r--r-- 1 myusername mygroup 45 Dec 13 07:07 myfile $ myfunc 敏捷的棕色狐狸跳过了懒狗。
即使
myfunc
被定义为 callmyalias
,并且我已经重新定义了myalias
,myfunc
仍然执行 的原始定义myalias
。因为别名是扩大当函数被定义时。事实上,shell 不再记得myfunc
调用myalias
;它只知道myfunc
调用cat
:$ 类型 myfunc myfunc 是一个函数 myfunc() { 猫我的文件 }
...函数中定义的别名只有在执行该函数之后才可用。
$ echo “敏捷的棕色狐狸跳过了懒狗。” > 我的文件 $ myfunc() { > 别名 myalias=cat > } $ myalias myfile -bash:myalias:找不到命令 $ myfunc $ myalias myfile 敏捷的棕色狐狸跳过了懒狗。
在执行该函数之前,别名
myalias
不可用。myfunc
(我认为,如果定义定义别名的函数足以导致定义别名,那就相当奇怪了。)
答案2
当我在我的代码中尝试下面的代码片段时,我需要第一句话所述的答案.bashrc
。
alias ls='\ls -F --color=auto --show-control-chars'
alias ll='ls -ahl'
function lf_macro() {
local CMD=${1:-ls} DIR=${2:-.};
$CMD $(find $DIR -maxdepth 1 -type f);
}
function lf() { lf_macro ll "$1"; }
function lsf() { lf_macro ls "$1"; } # list all file, no directories
之后unalias -a; source ~/.bashrc
,我尝试执行lf
并且lsf
,
$ lf
-bash: ll: command not found
$ lsf
./file1 ./file2 ./script.sh ... # no color, no control-chars
$ ls $(find -maxdepth 1 -type f)
./file1 ./file2 ./script.sh* ...
显然,别名是在函数定义时扩展的,而不是在函数执行时扩展的,因为:
- 当我执行时
lf
,出现错误-bash: ll: command not found
,并且 - 当我执行
lsf
,时/usr/bin/ls
,使用的不是别名形式,没有颜色突出显示,可执行文件后没有控制字符。
答案3
你可以说(例如)
别名 mvn="mvn -Dmaven.wagon.http.ssl.insecure=true $@"
IE 中,您可以在定义中重复别名的名称,但不能使用函数来做到这一点; bash 只会堆栈溢出并死掉。
可能有一种方法可以解决这个问题,但我不知道它是什么。