Bash 脚本的意外行为:首先执行函数,然后执行别名

Por*_*ine 5 scripting bash alias function

当我执行以下脚本时

#!/usr/bin/env bash

main() {
    shopt -s expand_aliases 
    alias Hi='echo "Hi from alias"'
    Hi  # Should Execute the alias
    \Hi # Should Execute the function
    "Hi"
}

function Hi() {
    echo "Hi from function"
}
main "$@"
Run Code Online (Sandbox Code Playgroud)

它第一次执行函数,然后总是作为别名执行:

$ . Sample.sh
Hi from function
Hi from function
Hi from function
$ . Sample.sh
Hi from alias
Hi from function
Hi from function
Run Code Online (Sandbox Code Playgroud)

为什么会这样?


在以下情况下不会发生这种情况

#!/usr/bin/env bash

function Hi() {
    echo "Hi from function"
}

shopt -s expand_aliases 
alias Hi='echo "Hi from alias"'
Hi  # Should Execute the alias
\Hi # Should Execute the function
"Hi"
Run Code Online (Sandbox Code Playgroud)

它第一次执行函数,然后总是作为别名执行:

$ . Sample.sh
Hi from alias
Hi from function
Hi from function
$ . Sample.sh
Hi from alias
Hi from function
Hi from function
Run Code Online (Sandbox Code Playgroud)

Bod*_*odo 10

函数中的别名扩展是在读取函数时完成的,而不是在执行函数时完成。函数中的别名定义在函数执行时执行。

See Alias and functions
and https://www.gnu.org/software/bash/manual/html_node/Aliases.html

This means, the alias will be defined when function main is executed, but when the function was read for the first time the alias was not yet defined. So the first time function main will execute function Hi three times.

When you source the script for the second time, the alias is already defined from the previous run and can be expanded when the function definition is read. When you now call the function it is run with the alias expanded.

The different behavior occurs only when the script is sourced with . Sample.sh, i.e. when it is run in the same shell several times. When you run it in a separate shell as ./Sample.sh it will always show the behavior of the first run.