A function definition is a command. When a function definition is run, I thought that the function body would be kept intact, as if the function body is single quoted.
I knew I was wrong, when I understood the following from the Bash manual in G-Man’s answer
to my Alias and functions question:
Aliases are expanded when a function definition is read, not when the function is executed, ….
So alias expansion is performed in the function body, while parameter expansion is not, as shown by the following example:
$ alias myalias=cat
$ echo $var
3
$ myfunc() { myalias myfile; echo $var; }
$ declare -fp myfunc
myfunc ()
{
cat myfile;
echo $var
}
Similarly, a call to a function is also a command.
aliases defined in a function are not available until after that function is executed.
so alias definition is executed only when executing, i.e., calling the function, not when running the function definition.
alias expansions and alias definition execution are just two of the shell operations listed below.
My questions are:
-
What shell operations are performed inside the function body, and
what operations are not performed,-
when running a function definition?
-
when calling a function, i.e., executing a function?
-
-
Are there any shell operations which are performed during both
running the definition of a function and calling the function?Or do running the definition of a function and calling the function
perform non-overlapping sets of shell operations?
The possible operations are listed in the following quote from the Bash manual:
3.1.1 Shell Operation
The following is a brief description of the shell’s operation when it reads and executes a command. Basically, the
shell does the following:
Reads its input from a file (see Section 3.8 [Shell Scripts], page 39), from a string supplied as an argument to the
-c
invocation option
(see Section 6.1 [Invoking Bash], page 80), or from the user’s
terminal.Breaks the input into words and operators, obeying the quoting rules described in Section 3.1.2 [Quoting], page 6. These tokens are
separated by metacharacters. Alias expansion is performed by this step
(see Section 6.6 [Aliases], page 88).Parses the tokens into simple and compound commands (see Section 3.2 [Shell Commands], page 8).
Performs the various shell expansions (see Section 3.5 [Shell Expansions], page 21), breaking the expanded tokens into lists of
filenames (see Section 3.5.8 [Filename Expansion], page 30) and
commands and arguments.Performs any necessary redirections (see Section 3.6 [Redirections], page 31) and removes the redirection operators and
their operands from the argument list.Executes the command (see Section 3.7 [Executing Commands], page 35).
Optionally waits for the command to complete and collects its exit status (see Section 3.7.5 [Exit Status], page 38).
Best Answer
Getting to your question, and looking at the seven steps / operations,
Parsing the tokens. This must at least start during the “processing the definition of a function” phase for the shell to realize that it is looking at a function definition and not a simple command. Beyond that, we can do this simple experiment: type either of the following into a shell:
It will fail with a “syntax error” before you get a chance to type the
}
. (>
and&
produce the same effect.) So clearly this step is part of processing the definition of the function.echo $var
(which should beecho "$var"
, but that’s another matter) toecho *
.echo *
and has not been expanded.cd
) and/or create file(s) and/or delete file(s) and/or rename file(s), and then call (execute) the function. You’ll see that it outputs the current list of files1 in the current directory, and doesn’t reflect the contents of the directory where/when you defined the function.echo $var
toecho hello > myfile
.> myfile
.myfile
has not been created (yet).In other words, exactly what @ilkkachu said.
The one exceptional special case I can think of is that steps 2 and 3 (lexical analysis and parsing) occur (again) when executing a function if the function contains
eval
statements — but I believe that that’s outside the scope of what your question is really asking.____________
1 excluding hidden (dot-) files, unless you have said
shopt -s dotglob