Let's start with a code that works
$ cat foo1
#!/bin/bash
foo() {
echo "I'm here";
}
foo # prints: I'm here
$ ./foo1
I'm here
$
so far so good.
Now let's introduce a syntax error
$ 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() { '
$
woops! let's fix it by unaliasing 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
$
what happens if we add an if condition?
$ 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() { '
$
Why? why is it failing inside an if condition, but used to work without the if condition?
what happens if we use the function foo{}
syntax instead of 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
$
It works now?
Question: why do foo2 and foo4 break?
Because the alias happens first, then the function definition turns into this (after bash substitutes the alias:
echo I am an alias() {
echo "I'm here";
}
and that's apparently a syntax error.
Aliases are only substituted on the first word of a command. When you use the function
keyword to define the function, then you're avoiding the possibility of alias expansion.
Ths is probably one of the reasons why aliases are turned off by default in non-interactive shells.