Help with understanding of alias

Hi, I saw the following explanation about alias in bash from gnu website, but I didn't get the meaning:
Bash always reads at least one complete line of input before executing any of the commands on that line.
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 compound command. As a consequence, aliases
defined in a function are not available until after that function is executed. To be safe, always put alias
definitions on a separate line, and do not use alias in compound commands.

especially the part related with function, can anybody help explain in short sentences cause I am not a English speaker.
Great Thanks.
Roy987

Here is an example:

# alias et='echo test'
# function doit {
> et
> }
# doit
test
# alias et='echo done'
# doit
test
# unalias et
# doit
test

See how changing the "et" alias makes no difference to the output. This is because et has already been expanded when the function was first defined.

2 Likes

The shell reads small chunks of the script which might be a single line from the file or might be a group of lines (a while or for loop is read all at once). As the shell reads these chunks the current alias definitions are applied to that chunk.

The same goes for functions. Each function in the script is read as a group of lines, and the aliases that are listed in the function are replaced as the function is read.

Consider this small example

function print_stuff
{
    p "$*"
}

alias p="echo \"$(hostname):\""   # alias p is not defined when function read

print_stuff "sample message"

It is common for a script to define all functions at the top of the script and to have a section just below for the initialisation of variables. A programmer might also think to define aliases in that initialisation section, but that's what the description is trying to point out as being wrong.

In the code above, the assumption is that because p is aliased before the function is executed, it will have the alias value at the time it is called. This is not the case.

As the shell reads the script, it reads in the function and because the alias p is not set when the function is read, the p in the function is not expanded. When the function is executed, an error message (no such command p, or something like that) is generated.

If the alias is defined before the function is read by the shell, then when the function is read p is expanded and all works as desired. The following is an example of this:

alias p="echo \"$(hostname):\""   #alias p will exist when function is read

function print_stuff
{
    p "$*"
}

p "sample message"

The same applies to a loop, but the "trap" is a bit different:

while read buffer
do
    if [[ $buffer == *"foo"* ]]
    then
       alias process_cmd="interpret_foo"
    else
       alias process_cmd="interpret_other"
    fi

    interpret_command  "$buffer"
done <some-file

This is an unrealistic example, but it illustrates what the text you posted is saying. The process_cmd alias will not be set until the while loop is executed, which means the command interpret_command "$buffer" will not be expanded.

I hope this helps. It is a difficult concept to put into words.

1 Like

Thanks a lot to agama, Chubler_XL, I can understand now.