让我们从一个可以工作的代码开始
$ cat foo1
#!/bin/bash
foo() {
echo "I'm here";
}
foo # prints: I'm here
$ ./foo1
I'm here
$
到目前为止一切顺利。
现在让我们引入一个语法错误
$ cat foo2
#!/bin/bash -i
alias foo="echo I am an alias"
foo() {
echo "I'm here";
}
foo # isn't reached
$ ./foo2
bash: ./foo2: line 4: syntax error near unexpected token `('
bash: ./foo2: line 4: `foo() { '
$
喷!让我们通过取消别名来修复它。
$ cat foo3
#!/bin/bash -i
alias foo="echo I am an alias"
unalias foo
foo() {
echo "I'm here";
}
foo # prints:
$ ./foo3
I'm here
$
如果添加if条件会发生什么?
$ cat foo4
#!/bin/bash -i
alias foo="echo I am an alias"
if true
then
unalias foo
foo() {
echo "I'm here";
}
fi
foo # prints:
$ ./foo4
bash: ./foo4: line 7: syntax error near unexpected token `('
bash: ./foo4: line 7: ` foo() { '
$
为什么?为什么它在if条件下会失败,而在没有if条件的情况下却可以工作?
如果我们使用function foo{}
语法而不是foo(){}
,会发生什么?
$ cat foo5
#!/bin/bash -i
alias foo="echo I am an alias"
if true
then
unalias foo
function foo {
echo "I'm here";
}
fi
foo # prints:
$ ./foo5
I'm here
$
它现在工作了吗?
问题:为什么foo2和foo4会断开?
-
因为先出现别名,所以函数定义变成这样(在bash替换别名之后):
echo I am an alias() { echo "I'm here"; }
这显然是一个语法错误
-
别名只能在命令的第一个单词上被替换。当您使用
function
关键字来定义函数时,那么您就避免了别名扩展的可能性。
这可能是在非交互式shell中默认关闭别名的原因之一。
我只是添加引用,因为接受的答案(连同第一条注释)是正确的。
来自bash
手册页:
The rules concerning the definition and use of aliases are somewhat
confusing. Bash always reads at least one complete line of input, and
all lines that make up a compound command, before executing any of the
commands on that line or the compound command. Aliases are expanded
when a command is read, not when it is executed. Therefore, an alias
definition appearing on the same line as another command does not take
effect until the next line of input is read. The commands following
the alias definition on that line are not affected by the new alias.
This behavior is also an issue when functions are executed. Aliases
are expanded when a function definition is read, not when the function
is executed, because a function definition is itself a command. As a
consequence, aliases defined in a function are not available until af‐
ter that function is executed. To be safe, always put alias defini‐
tions on a separate line, and do not use alias in compound commands.
魔鬼在细节(f#*@!)n"手动).