使用foo(){}语法的if语句中bash函数定义的奇怪行为



让我们从一个可以工作的代码开始

$ 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会断开?

  1. 因为先出现别名,所以函数定义变成这样(在bash替换别名之后):

    echo I am an alias() { 
    echo "I'm here";
    }
    

    这显然是一个语法错误

  2. 别名只能在命令的第一个单词上被替换。当您使用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"手动).

相关内容

  • 没有找到相关文章

最新更新